﻿using System;
using System.Linq;
using System.Text;
using Newtonsoft.Json;
using System.IO.Packaging;
using System.Threading.Tasks;
using MedianSocketService.Enum;
using DotNetty.Common.Utilities;
using MedianSocketService.utils;
using System.Threading.Channels;
using MedianSocketService.netty;
using System.Collections.Generic;
using MedianSocketService.Models;
using MedianSocketService.Struct;
using DotNetty.Transport.Channels;
using MedianSocketService.ProtocolParams;

namespace MedianSocketService.services
{
    public class MedianProtocolService
    {
        #region ___字段___

        /// <summary>
        /// Socket字段
        /// </summary>
        public SocketClientInfo sci { get; set; }
        private static AutoResetEvent activateSignal = new AutoResetEvent(false);
        private static object lockobj = new object();
        public static List<HistorySampleData> historyCacheQueue = new List<HistorySampleData>();
        #endregion ___字段___

        #region ___解数据包___

        /// <summary>
        /// 接包数据
        /// </summary>
        /// <param name="btFrameData"></param>
        public void UnPack(byte[] btFrameData)
        {
            if (btFrameData == null || btFrameData.Length < 15)
            {
                //一个完整的包最简单结构： 包头(13)+包体(*)+包尾(2)
                //包长度小于15 认为不是一个完整的包结构--下面使用到了 命令Command 所以在这里简单判断长度
                return;
            }
            /********复制出来包头、包体、包尾*************/
            //包头
            byte[] dataHeader = new byte[13];
            Array.Copy(btFrameData, 0, dataHeader, 0, dataHeader.Length);
            //包体
            // 计算包体+包尾长度（小端字节序）
            int bodyLength = (btFrameData[12] << 8) + btFrameData[11];
            byte[] dataBody = new byte[bodyLength - 2];
            Array.Copy(btFrameData, 13, dataBody, 0, dataBody.Length);
            //包尾
            byte[] dataTail = new byte[2];
            Array.Copy(btFrameData, btFrameData.Length - 2, dataTail, 0, dataTail.Length);
            //校验CRC
            byte[] crcData = new byte[btFrameData.Length - 2];
            Array.Copy(btFrameData, 0, crcData, 0, btFrameData.Length - 2);
            byte[] crc = Crc16(crcData).ToArray();
            if (crc[0] != btFrameData[btFrameData.Length - 2] && crc[1] != btFrameData[btFrameData.Length - 1])
            {
                //CRC校验不通过
                return;
            }
            //命名码
            int nCommand = (dataHeader[10] << 8) + dataHeader[9];

            //心跳(0x1000)
            if (nCommand == 4096)
            {
                LifeFrameResponse(nCommand, dataBody);
            }
            else if (nCommand == 4097 || nCommand == 8193
                    || nCommand == 8194 || nCommand == 8195)
            {
                //时间同步 4097(0x1001)
                //设备控制指令-运行 8193(0x2001)
                //设备控制指令-停止 8194(0x2002)
                //设备控制指令-暂停 8195(0x2003)
                SimpleResponse(nCommand, dataBody);
            }
            else if (nCommand == 4098)
            {
                //3.获取设备系统时间 4098(0x1002)
                DeviceSysTimeResponse(nCommand, dataBody);
            }
            else if (nCommand == 8196 || nCommand == 8197
                    || nCommand == 8198 || nCommand == 8199)
            {
                //设备控制指令-接续 8196(0x2004)
                //设备控制指令-跳转 8197(0x2005)
                //设备控制指令-重置 8198(0x2006)
                //设备控制指令-迁移 8199(0x2007)
                SimpleWithChannelResponse(nCommand, dataBody);
            }
            else if (nCommand == 12290)
            {
                //下发工步数据 0x3002
                WorkStepDataResponse(nCommand, dataBody);
            }
            else if (nCommand == 12289)
            {
                //下发全局参数 0x3001
                GlobalWorkStepDataResponse(nCommand, dataBody);
            }
            else if (nCommand == 12291)
            {
                // '读取全局参数'指令 12291(0x3003)
                ReadGlobalWorkStepDataResponse(nCommand, dataBody);
            }
            else if (nCommand == 12292)
            {
                // '读取工步数据'指令 12292(0x3004)
                ReadWorkStepDataResponse(nCommand, dataBody);
            }
            else if (nCommand == 12293)
            {
                // '读取工步校验码'指令 12293(0x3005)
                ReadWorkStepCheckSumResponse(nCommand, dataBody);
            }
            else if (nCommand == 20480)
            {

                lock (historyCacheQueue)
                {
                    historyCacheQueue.Clear();
                }
            }
        }

        #endregion ___解数据包___

        #region 回应设备系统时间

        private void DeviceSysTimeResponse(int nCommand, byte[] dataBody)
        {
            List<byte> commandCode = new List<byte>();
            List<byte> byteData = new List<byte>();
            //命令码 2
            commandCode.AddRange(MyByteUtil.IntToByte2(nCommand));
            //时间
            DateTime now = DateTime.Now;
            STLocTime stLocTime = new STLocTime();
            stLocTime.Seconds = (uint)now.Second;
            stLocTime.Minutes = (uint)now.Minute;
            stLocTime.Hours = (uint)now.Hour;
            stLocTime.Day = (uint)now.Day;
            stLocTime.Month = (uint)now.Month;
            stLocTime.Year = ((uint)(now.Year % 2000));

            uint sysTime = stLocTime.uiLoTime;
            byte[] byteArr = BitConverter.GetBytes(sysTime);
            byteData.AddRange(byteArr);
            //返回码
            byteData.Add(0x00);
            //添加包头和包尾
            List<byte[]> listRet = AddHeaderAndTail(commandCode.ToArray(), byteData.ToArray());
            foreach (byte[] brData in listRet)
            {
                ChannelManager.GetInstance().SendDataToClient(sci, brData);
            }
        }

        #endregion 回应设备系统时间

        #region 回应 读取工步校验码

        private void ReadWorkStepCheckSumResponse(int nCommand, byte[] dataBody)
        {
            /********回应数据***************/
            List<byte> commandCode = new List<byte>();
            List<byte> byteData = new List<byte>();
            //命令码 2
            commandCode.AddRange(MyByteUtil.IntToByte2(nCommand));
            //通道号  2
            byteData.Add(dataBody[0]); byteData.Add(dataBody[1]);
            Random random = new Random();
            WorkStepCheckSum workStepCheckSum = new WorkStepCheckSum();
            //workStepCheckSum.crcBytes = new List<byte>();
            //workStepCheckSum.crcBytes.AddRange(IntToByte2(random.Next(1, 200)));
            Guid guid = Guid.NewGuid();
            workStepCheckSum.uuid = BitConverter.ToUInt32(guid.ToByteArray(), 0);
            workStepCheckSum.stepNo = random.Next(1, 50);
            // byteData.AddRange(workStepCheckSum.crcBytes.ToArray());
            //UUID 4
            byte[] byteUuid = BitConverter.GetBytes(workStepCheckSum.uuid);
            if (!BitConverter.IsLittleEndian)
            {
                byteUuid.Reverse();
            }
            byteData.AddRange(byteUuid);
            //工步数量    2   工步数量
            byteData.AddRange(IntToByte2(workStepCheckSum.stepNo));
            //预留	10	预留字节
            byteData.AddRange(new byte[10]);
            //添加包头和包尾
            List<byte[]> listRet = AddHeaderAndTail(commandCode.ToArray(), byteData.ToArray());
            foreach (byte[] brData in listRet)
            {
                ChannelManager.GetInstance().SendDataToClient(sci, brData);
            }

            //弹出
            JsonSerializerSettings settings = new JsonSerializerSettings
            {
                NullValueHandling = NullValueHandling.Include,
                Formatting = Formatting.Indented,
            };
            string strjson = JsonConvert.SerializeObject(workStepCheckSum, settings);
            UseFormShowMsg(strjson);
        }

        #endregion 回应 读取工步校验码

        #region 回应 读取工步数据

        private void ReadWorkStepDataResponse(int nCommand, byte[] dataBody)
        {
            /********回应数据***************/
            List<byte> commandCode = new List<byte>();
            List<byte> byteData = new List<byte>();
            //命令码 2
            commandCode.AddRange(MyByteUtil.IntToByte2(nCommand));
            //通道号  2
            byteData.Add(dataBody[0]); byteData.Add(dataBody[1]);
            //全局参数数据	N	参考全局参数数据结构
            List<WorkStepDataParam> workStepDataParams = GetWorkStepDataParams(3);
            byteData.AddRange(SerializeWorkStepData(workStepDataParams));
            //预留	10	预留字节
            byteData.AddRange(new byte[10]);
            //添加包头和包尾
            List<byte[]> listRet = AddHeaderAndTail(commandCode.ToArray(), byteData.ToArray());
            foreach (byte[] brData in listRet)
            {
                ChannelManager.GetInstance().SendDataToClient(sci, brData);
            }

            //弹出
            JsonSerializerSettings settings = new JsonSerializerSettings
            {
                NullValueHandling = NullValueHandling.Include,
                Formatting = Formatting.Indented,
            };
            string strjson = JsonConvert.SerializeObject(workStepDataParams, settings);
            UseFormShowMsg(strjson);
        }

        private byte[] SerializeWorkStepData(List<WorkStepDataParam> workStepDataParams)
        {
            List<byte> byteData = new List<byte>();
            foreach (WorkStepDataParam stepData in workStepDataParams)
            {
                //uint8_t  工步类型    1   参考工步类型说明
                byteData.Add(Convert.ToByte(stepData.stepType & 0xFF));
                //uint16_t    工步序号    2   工步序号
                byteData.AddRange(IntToByte2(stepData.stepNo));

                #region 工步运行主参数1,2,3

                /***************Int32[] 工步运行主参数 1,2,3 **********************/
                //a[0]
                if (stepData.stepType == (int)EnumWorkStepType.ConstantCurrentCharge
                    || stepData.stepType == (int)EnumWorkStepType.ConstantCurrentDischarge
                    || stepData.stepType == (int)EnumWorkStepType.ConstantCurrentAndVoltageCharge
                    || stepData.stepType == (int)EnumWorkStepType.ConstantCurrentAndVoltageDischarge
                    || stepData.stepType == (int)EnumWorkStepType.ConstantPowerCharge
                    || stepData.stepType == (int)EnumWorkStepType.ConstantPowerDischarge
                    || stepData.stepType == (int)EnumWorkStepType.ConstantResistanceDischarge)
                {
                    //恒流充电,恒流放电,恒流恒压充电,恒流恒压放电，恒功率充电，恒功率放电，恒阻放电
                    byteData.AddRange(IntToByte4(1));
                }
                else if (stepData.stepType == (int)EnumWorkStepType.Loop && stepData.stepMainParam != null)
                {
                    //循环 [0]：跳转的工步号;
                    byteData.AddRange(IntToByte4(stepData.stepMainParam.jumpStepNo));
                }
                else
                {
                    byteData.AddRange(IntToByte4(0));
                }
                //a[1]
                if (stepData.stepType == (int)EnumWorkStepType.ConstantVoltageCharge
                    || stepData.stepType == (int)EnumWorkStepType.ConstantVoltageDischarge
                    || stepData.stepType == (int)EnumWorkStepType.ConstantCurrentAndVoltageCharge
                    || stepData.stepType == (int)EnumWorkStepType.ConstantCurrentAndVoltageDischarge)
                {
                    //恒压充电,恒压放电,恒流恒压充电,恒流恒压放电
                    byteData.AddRange(IntToByte4(1));
                }
                else if (stepData.stepType == (int)EnumWorkStepType.Loop && stepData.stepMainParam != null)
                {
                    //循环 [1]:循环总数
                    byteData.AddRange(IntToByte4(stepData.stepMainParam.loopNumber));
                }
                else
                {
                    byteData.AddRange(IntToByte4(0));
                }
                //a[2]
                byteData.AddRange(IntToByte4(0));

                #endregion 工步运行主参数1,2,3

                #region 环境控制参数 30

                if (stepData.environmentControlParam != null)
                {
                    //uint8_t 设备类型    1   0 - 无效；1 - 真空控制；2 - 压力控制；3 - 温箱控制；
                    byteData.Add(Convert.ToByte(stepData.environmentControlParam.DeviceType & 0xFF));
                    //uint8_t 动作类型    1   0 - 无效；
                    //不同设备类型对应不同的动作类型：
                    //真空控制设备: 1 - 关闭；2 - 高真空；3 - 低真空；4 - 微正压
                    //压力控制设备: 1 - 关闭；2 - 压力设置
                    //温箱控制设备: 1 - 关闭；2 - 温度设置
                    byteData.Add(Convert.ToByte(stepData.environmentControlParam.ActionType));

                    //uint32_t 控制值 4   控制值
                    byteData.AddRange(IntToByte4(stepData.environmentControlParam.ControlValue));
                    //uint32_t 开始时间	4	工步运行到指定时间开始控制,时间值(S)
                    byteData.AddRange(IntToByte4(stepData.environmentControlParam.StartTime));
                    //uint32_t 持续时间	4	控制的总时长，时间值(S)
                    byteData.AddRange(IntToByte4(stepData.environmentControlParam.DurationTime));
                    //uint32_t    预留  4 * 4 预留
                    byteData.AddRange(new byte[4 * 4]);
                }
                else
                {
                    byteData.AddRange(new byte[30]);
                }

                #endregion 环境控制参数 30

                //uint8_t 倍率模式    1   0 - 无效；1 - 设置标称容量模式; 2 - 指定工步所得容量为标称容量模式
                byteData.Add(Convert.ToByte(stepData.rateMode));
                //uint16_t 标称容量指定工步号   2   标称容量指定工步号，从1开始
                byteData.AddRange(IntToByte2(stepData.nominalCapacityStepNo));
                //uint32_t    标称容量    4   标称容量值(Ah)
                byteData.AddRange(IntToByte4(stepData.nominalCapacity));

                #region 工步设定开关 4

                //uint32_t	工步设定开关	4	每bit对应一种开关，0-无效；1-开；
                List<int> checkSwitch = new List<int>();
                if (stepData.isCutoffTimeEnabled)
                {
                    //截至时间bit0 开关
                    checkSwitch.Add(1);
                }
                if (stepData.isCutoffCurrentEnabled)
                {
                    //截至电流bit1 开关
                    checkSwitch.Add(2);
                }
                if (stepData.isCutoffVoltageEnabled)
                {
                    //截至电压bit2
                    checkSwitch.Add(3);
                }
                if (stepData.isCutoffCapacityEnabled)
                {
                    //截至容量bit3
                    checkSwitch.Add(4);
                }

                if (stepData.isVoltageUpperLimitEnabled)
                {
                    //电压上限bit4
                    checkSwitch.Add(5);
                }
                if (stepData.isVoltageLowerLimitEnabled)
                {
                    //电压下限bit5
                    checkSwitch.Add(6);
                }
                if (stepData.isCurrentUpperLimitEnabled)
                {
                    //电流上限bit6
                    checkSwitch.Add(7);
                }
                if (stepData.isCurrentLowerLimitEnabled)
                {
                    //电流下限bit7
                    checkSwitch.Add(8);
                }
                if (stepData.isCapacityUpperLimitEnabled)
                {
                    //容量上限bit8
                    checkSwitch.Add(9);
                }
                if (stepData.isTemperatureUpperLimitEnabled)
                {
                    //电池温度上限bit9
                    checkSwitch.Add(10);
                }
                if (stepData.isTemperatureLowerLimitEnabled)
                {
                    //电池温度下限bit10
                    checkSwitch.Add(11);
                }
                if (stepData.isEnvTemperatureUpperLimitEnabled)
                {
                    //环境温度上限bit11
                    checkSwitch.Add(12);
                }
                if (stepData.isEnvTemperatureLowerLimitEnabled)
                {
                    //环境温度下限bit12
                    checkSwitch.Add(13);
                }
                if (stepData.isVacuumUpperLimitEnabled)
                {
                    //真空上限bit13
                    checkSwitch.Add(14);
                }
                if (stepData.isVacuumLowerLimitEnabled)
                {
                    //真空下限bit14
                    checkSwitch.Add(15);
                }
                if (stepData.isBatteryTemperatureChangeRateEnabled)
                {
                    //电池温度变化率bit15
                    checkSwitch.Add(16);
                }
                if (stepData.isVoltageChangeRateEnabled)
                {
                    //电压变化率bit16
                    checkSwitch.Add(17);
                }
                if (stepData.isOtherChangeRateEnabled)
                {
                    //其他类型变化率bit17
                    checkSwitch.Add(18);
                }
                if (stepData.isVoltageInTimePeriodEnabled)
                {
                    //指定时间内电压bit18
                    checkSwitch.Add(19);
                }
                byteData.AddRange(ConvertIntToByteFlag(checkSwitch, 4));

                #endregion 工步设定开关 4

                #region 工步开关数据值

                //uint8_t 条件达到动作类型    1   0 - 下一步， 1 - 停止，2 - 结束
                byteData.Add(Convert.ToByte(stepData.conditionMetActionType));
                //uint32_t	截至时间bit0	4	时间值(S)
                byteData.AddRange(IntToByte4(stepData.cutoffTime));
                //uint32_t	截至电流bit1	4	电流值(A)
                byteData.AddRange(IntToByte4(stepData.cutoffCurrent));
                //uint32_t	截至电压bit2	4	电压值(V)
                byteData.AddRange(IntToByte4(stepData.cutoffVoltage));
                //uint32_t	截至容量bit3	4	容量值(Ah)
                byteData.AddRange(IntToByte4(stepData.cutoffCapacity));
                //uint32_t	电压上限bit4	4	电压值(V)
                byteData.AddRange(IntToByte4(stepData.voltageUpperLimit));
                //uint32_t	电压下限bit5	4	电压值(V)
                byteData.AddRange(IntToByte4(stepData.voltageLowerLimit));
                //uint32_t	电流上限bit6	4	电流值(A)
                byteData.AddRange(IntToByte4(stepData.currentUpperLimit));
                //uint32_t	电流下限bit7	4	电流值(A)
                byteData.AddRange(IntToByte4(stepData.currentLowerLimit));
                //uint32_t	容量上限bit8	4	容量值(Ah)
                byteData.AddRange(IntToByte4(stepData.capacityUpperLimit));
                //uint32_t	电池温度上限bit9	4	温度值(℃)
                byteData.AddRange(IntToByte4(stepData.temperatureUpperLimit));
                //uint32_t	电池温度下限bit10	4	温度值(℃)
                byteData.AddRange(IntToByte4(stepData.temperatureLowerLimit));
                //uint32_t	环境温度上限bit11	4	温度值(℃)
                byteData.AddRange(IntToByte4(stepData.envTemperatureUpperLimit));
                //uint32_t	环境温度下限bit12	4	温度值(℃)
                byteData.AddRange(IntToByte4(stepData.envTemperatureLowerLimit));
                //uint32_t	真空上限bit13	4	真空值(kPa)
                byteData.AddRange(IntToByte4(stepData.vacuumUpperLimit));
                //uint32_t	真空下限bit14	4	真空值(kPa)
                byteData.AddRange(IntToByte4(stepData.vacuumLowerLimit));
                //Null 电池温度变化率   10  参考变化率数据结构
                if (stepData.batteryTemperatureChangeRate != null)
                {
                    //uint8_t 比较类型    1   0：≥； 1： ≤;
                    byteData.Add(Convert.ToByte(stepData.batteryTemperatureChangeRate.CompareType & 0xFF));
                    //uint8_t 比较次数    1   范围1 - 255
                    byteData.Add(Convert.ToByte(stepData.batteryTemperatureChangeRate.CompareCount & 0xFF));
                    //uint32_t 比较绝对值   4   比较值
                    byteData.AddRange(IntToByte4(stepData.batteryTemperatureChangeRate.CompareValue));
                    //uint32_t    比较间隔时间  4   间隔时间
                    byteData.AddRange(IntToByte4(stepData.batteryTemperatureChangeRate.CompareInterval));
                }
                else
                {
                    byteData.AddRange(new byte[10]);
                }

                //Null    电压变化率  10  参考变化率数据结构
                if (stepData.voltageChangeRate != null)
                {
                    //uint8_t 比较类型    1   0：≥； 1： ≤;
                    byteData.Add(Convert.ToByte(stepData.voltageChangeRate.CompareType & 0xFF));
                    //uint8_t 比较次数    1   范围1 - 255
                    byteData.Add(Convert.ToByte(stepData.voltageChangeRate.CompareCount & 0xFF));
                    //uint32_t 比较绝对值   4   比较值
                    byteData.AddRange(IntToByte4(stepData.voltageChangeRate.CompareValue));
                    //uint32_t    比较间隔时间  4   间隔时间
                    byteData.AddRange(IntToByte4(stepData.voltageChangeRate.CompareInterval));
                }
                else
                {
                    byteData.AddRange(new byte[10]);
                }
                //Uint8_t 其他类型变化率    1   变化率类型 预留
                byteData.Add((byte)0);
                //Null 其他类型变化率    10  参考变化率数据结构
                if (stepData.otherChangeRate != null)
                {
                    //uint8_t 比较类型    1   0：≥； 1： ≤;
                    byteData.Add(Convert.ToByte(stepData.otherChangeRate.CompareType & 0xFF));
                    //uint8_t 比较次数    1   范围1 - 255
                    byteData.Add(Convert.ToByte(stepData.otherChangeRate.CompareCount & 0xFF));
                    //uint32_t 比较绝对值   4   比较值
                    byteData.AddRange(IntToByte4(stepData.otherChangeRate.CompareValue));
                    //uint32_t    比较间隔时间  4   间隔时间
                    byteData.AddRange(IntToByte4(stepData.otherChangeRate.CompareInterval));
                }
                else
                {
                    byteData.AddRange(new byte[10]);
                }
                //uint32_t    指定时间内电压    4   指定时间值(S)
                byteData.AddRange(IntToByte4(stepData.voltageInTimePeriod));
                //uint32_t    时间内电压最大值   4   指定时间内电压最大值(V)
                byteData.AddRange(IntToByte4(stepData.maxVoltageInTimePeriod));
                //uint32_t    时间内电压最小值   4   指定时间内电压最小值(V)
                byteData.AddRange(IntToByte4(stepData.minVoltageInTimePeriod));
                //Null    预留  10 * 4    预留
                byteData.AddRange(new byte[10 * 4]);

                #endregion 工步开关数据值
            }

            return byteData.ToArray();
        }

        private List<WorkStepDataParam> GetWorkStepDataParams(int nCount)
        {
            Random random = new Random();
            List<WorkStepDataParam> workStepDataParams = new List<WorkStepDataParam>();
            for (int n = 1; n <= nCount; n++)
            {
                WorkStepDataParam stepData = new WorkStepDataParam();
                //uint8_t 工步类型    1   参考工步类型说明
                stepData.stepType = (int)EnumWorkStepType.Loop;
                //uint16_t    工步序号    2   工步序号
                stepData.stepNo = n;
                //Int32[] 工步运行主参数 10 * 4    参考工步主参数结构
                stepData.stepMainParam = new StepMainParam();
                stepData.stepMainParam.jumpStepNo = n;
                stepData.stepMainParam.loopNumber = random.Next(1, 100);
                //Null    环境控制参数  30  参考环境控制参数结构
                stepData.environmentControlParam = new EnvironmentControlParam();
                stepData.environmentControlParam.DeviceType = 1;
                stepData.environmentControlParam.ActionType = n;
                stepData.environmentControlParam.ControlValue = random.Next(1, 100);
                //uint8_t 倍率模式    1   0 - 无效；1 - 设置标称容量模式; 2 - 指定工步所得容量为标称容量模式
                stepData.rateMode = random.Next(1, 100);
                //uint16_t 标称容量指定工步号   2   标称容量指定工步号，从1开始
                stepData.nominalCapacityStepNo = random.Next(1, 100);
                //uint32_t    标称容量    4   标称容量值(Ah)
                stepData.nominalCapacity = random.Next(1, 100);
                //uint8_t 工步截至检测开关    1   每bit对应一种开关，0 - 无效；1 - 开；
                stepData.isCutoffTimeEnabled = true;
                stepData.isCutoffCurrentEnabled = false;
                stepData.isCutoffVoltageEnabled = false;
                stepData.isCutoffCapacityEnabled = true;
                //uint8_t 条件达到动作类型    1   0 - 下一步， 1 - 停止，2 - 结束
                stepData.conditionMetActionType = random.Next(1, 100);
                //uint32_t 截至时间bit0    4   时间值(S)
                stepData.cutoffTime = random.Next(1, 100);
                //uint32_t 截至电流bit1    4   电流值(A)
                stepData.cutoffCurrent = random.Next(1, 100);
                //uint32_t 截至电压bit2    4   电压值(V)
                stepData.cutoffVoltage = random.Next(1, 100);
                //uint32_t 截至容量bit3    4   容量值(Ah)
                stepData.cutoffCapacity = random.Next(1, 100);

                //uint32_t 工步保护条件开关    4   每bit对应一种开关，0 - 关，1 - 开；
                //电压上限bit0
                stepData.isVoltageUpperLimitEnabled = true;

                //电压下限bit1
                stepData.isVoltageLowerLimitEnabled = false;

                //电流上限bit2
                stepData.isCurrentUpperLimitEnabled = true;

                //电流下限bit3
                stepData.isCurrentLowerLimitEnabled = true;

                //容量上限bit4
                stepData.isCapacityUpperLimitEnabled = false;

                //电池温度上限bit6
                stepData.isTemperatureUpperLimitEnabled = true;

                //电池温度下限bit7
                stepData.isTemperatureLowerLimitEnabled = false;

                //环境温度上限bit8
                stepData.isEnvTemperatureUpperLimitEnabled = true;

                //环境温度下限bit9
                stepData.isEnvTemperatureLowerLimitEnabled = true;

                //真空上限bit10
                stepData.isVacuumUpperLimitEnabled = true;

                //真空下限bit11
                stepData.isVacuumLowerLimitEnabled = false;

                //电池温度变化率bit12
                stepData.isBatteryTemperatureChangeRateEnabled = true;

                //电压变化率bit13
                stepData.isVoltageChangeRateEnabled = true;

                //电流变化率bit14
                //stepData.isCurrentChangeRateEnabled = true;

                //其他类型变化率bit15
                stepData.isOtherChangeRateEnabled = false;

                //指定时间内电压bit16
                stepData.isVoltageInTimePeriodEnabled = false;

                //uint32_t 电压上限bit0    4   电压值(V)
                stepData.voltageUpperLimit = random.Next(1, 100);
                //uint32_t 电压下限bit1    4   电压值(V)
                stepData.voltageLowerLimit = random.Next(1, 100);
                //uint32_t 电流上限bit2    4   电流值(A)
                stepData.currentUpperLimit = random.Next(1, 100);
                //uint32_t 电流下限bit3    4   电流值(A)
                stepData.currentLowerLimit = random.Next(1, 100);
                //uint32_t 容量上限bit4    4   容量值(Ah)
                stepData.capacityUpperLimit = random.Next(1, 100);
                //uint32_t 电池温度上限bit6  4   温度值(℃)
                stepData.temperatureUpperLimit = random.Next(1, 100);
                //uint32_t 电池温度下限bit7  4   温度值(℃)
                stepData.temperatureLowerLimit = random.Next(1, 100);
                //uint32_t 环境温度上限bit8  4   温度值(℃)
                stepData.envTemperatureUpperLimit = random.Next(1, 100);
                //uint32_t 环境温度下限bit9  4   温度值(℃)
                stepData.envTemperatureLowerLimit = random.Next(1, 100);
                //uint32_t 真空上限bit10   4   真空值(kPa)
                stepData.vacuumUpperLimit = random.Next(1, 100);
                //uint32_t 真空下限bit11   4   真空值(kPa)
                stepData.vacuumLowerLimit = random.Next(1, 100);

                /*********Null 电池温度变化率bit12    10  参考变化率数据结构**********/
                stepData.batteryTemperatureChangeRate = new RateChangeData();
                //uint8_t 比较类型    1   0：≥； 1： ≤;
                stepData.batteryTemperatureChangeRate.CompareType = random.Next(1, 100);
                //uint8_t 比较次数    1   范围1 - 255
                stepData.batteryTemperatureChangeRate.CompareCount = random.Next(1, 100);
                //uint32_t 比较绝对值   4   比较值
                stepData.batteryTemperatureChangeRate.CompareValue = random.Next(1, 100);
                //uint32_t    比较间隔时间  4   间隔时间
                stepData.batteryTemperatureChangeRate.CompareInterval = random.Next(1, 100);

                /*********Null    电压变化率bit13  10  参考变化率数据结构**********/
                stepData.voltageChangeRate = new RateChangeData();
                //uint8_t 比较类型    1   0：≥； 1： ≤;
                stepData.voltageChangeRate.CompareType = random.Next(1, 100);
                //uint8_t 比较次数    1   范围1 - 255
                stepData.voltageChangeRate.CompareCount = random.Next(1, 100);
                //uint32_t 比较绝对值   4   比较值
                stepData.voltageChangeRate.CompareValue = random.Next(1, 100);
                //uint32_t    比较间隔时间  4   间隔时间
                stepData.voltageChangeRate.CompareInterval = random.Next(1, 100);

                /*********Null    电流变化率bit14  10  参考变化率数据结构**********/
                //stepData.currentChangeRate = new RateChangeData();
                ////uint8_t 比较类型    1   0：≥； 1： ≤;
                //stepData.currentChangeRate.CompareType = random.Next(1, 100);
                ////uint8_t 比较次数    1   范围1 - 255
                //stepData.currentChangeRate.CompareCount = random.Next(1, 100);
                ////uint32_t 比较绝对值   4   比较值
                //stepData.currentChangeRate.CompareValue = random.Next(1, 100);
                ////uint32_t    比较间隔时间  4   间隔时间
                //stepData.currentChangeRate.CompareInterval = random.Next(1, 100);

                //Uint8_t 其他类型变化率bit15    1   变化率类型 预留
                /*********Null 其他类型变化率bit15    10  参考变化率数据结构**********/
                stepData.otherChangeRate = new RateChangeData();
                //uint8_t 比较类型    1   0：≥； 1： ≤;
                stepData.otherChangeRate.CompareType = random.Next(1, 100);
                //uint8_t 比较次数    1   范围1 - 255
                stepData.otherChangeRate.CompareCount = random.Next(1, 100);
                //uint32_t 比较绝对值   4   比较值
                stepData.otherChangeRate.CompareValue = random.Next(1, 100);
                //uint32_t    比较间隔时间  4   间隔时间
                stepData.otherChangeRate.CompareInterval = random.Next(1, 100);

                //uint32_t    指定时间内电压bit16    4   指定时间值
                stepData.voltageInTimePeriod = random.Next(1, 100);
                //uint32_t    时间内电压最大值bit16   4   指定时间内电压最大值
                stepData.maxVoltageInTimePeriod = random.Next(1, 100);
                //uint32_t    时间内电压最小值bit16   4   指定时间内电压最小值
                stepData.minVoltageInTimePeriod = random.Next(1, 100);

                //Null    预留  20 * 4    预留

                workStepDataParams.Add(stepData);
            }
            return workStepDataParams;
        }

        #endregion 回应 读取工步数据

        #region 回应 读取全局参数

        private void ReadGlobalWorkStepDataResponse(int nCommand, byte[] dataBody)
        {
            /********回应数据***************/
            List<byte> commandCode = new List<byte>();
            List<byte> byteData = new List<byte>();
            //命令码 2
            commandCode.AddRange(MyByteUtil.IntToByte2(nCommand));
            //通道号  2
            byteData.Add(dataBody[0]); byteData.Add(dataBody[1]);
            //全局参数数据	N	参考全局参数数据结构
            GlobalWorkStepParam globalWorkStepParam = GetGlobalWorkStepData();
            byteData.AddRange(SerializeGlobalStepData(globalWorkStepParam));
            //预留	10	预留字节
            byteData.AddRange(new byte[10]);
            //添加包头和包尾
            List<byte[]> listRet = AddHeaderAndTail(commandCode.ToArray(), byteData.ToArray());
            if (listRet.Count > 0)
            {
                ChannelManager.GetInstance().SendDataToClient(sci, listRet.First());
            }

            //弹出
            JsonSerializerSettings settings = new JsonSerializerSettings
            {
                NullValueHandling = NullValueHandling.Include,
                Formatting = Formatting.Indented,
            };
            string strjson = JsonConvert.SerializeObject(globalWorkStepParam, settings);
            UseFormShowMsg(strjson);
        }

        private byte[] SerializeGlobalStepData(GlobalWorkStepParam globalWorkStepParam)
        {
            List<byte> byteData = new List<byte>();

            //uint16_t 校验码 2   工步数据的Crc校验码
            // byte[] btWorkStep = SerializeStepData(workStepDataParams);
            // byte[] crc = Crc16(btWorkStep).ToArray();
            globalWorkStepParam.crcWorkStepParam = new List<byte> { 1, 2 };
            byteData.AddRange(globalWorkStepParam.crcWorkStepParam.ToArray());

            //uint16_t    工步数量    2   工步数量
            globalWorkStepParam.nWorkStepNum = 2;
            byteData.AddRange(IntToByte2(globalWorkStepParam.nWorkStepNum));

            #region 全局设定开关

            List<int> dataGlobalSwitch = new List<int>();
            if (globalWorkStepParam.isDataRecordTimeValEnabled)
            {
                //uint32_t 数据记录时间值bit0
                dataGlobalSwitch.Add(1);
            }
            if (globalWorkStepParam.isDataRecordVoltageValEnabled)
            {
                //uint32_t 数据记录电压值bit1
                dataGlobalSwitch.Add(2);
            }
            if (globalWorkStepParam.isDataRecordCurrentValEnabled)
            {
                //uint32_t 数据记录电流值bit2
                dataGlobalSwitch.Add(3);
            }
            if (globalWorkStepParam.isVoltageUpperLimitEnabled)
            {
                //uint32_t 电压上限bit3
                dataGlobalSwitch.Add(4);
            }
            if (globalWorkStepParam.isVoltageLowerLimitEnabled)
            {
                //uint32_t 电压下限bit4
                dataGlobalSwitch.Add(5);
            }
            if (globalWorkStepParam.isChargeCurrentUpperLimitEnabled)
            {
                //uint32_t 充电电流上限bit5
                dataGlobalSwitch.Add(6);
            }
            if (globalWorkStepParam.isDischargeCurrentUpperLimitEnabled)
            {
                //uint32_t 放电电流上限bit6
                dataGlobalSwitch.Add(7);
            }
            if (globalWorkStepParam.isTemperatureUpperLimitEnabled)
            {
                //uint32_t 电池温度上限bit7
                dataGlobalSwitch.Add(8);
            }
            if (globalWorkStepParam.isTemperatureLowerLimitEnabled)
            {
                //uint32_t 电池温度下限bit8
                dataGlobalSwitch.Add(9);
            }
            if (globalWorkStepParam.isChargeCapacityUpperLimitEnabled)
            {
                //uint32_t 充电容量上限bit9
                dataGlobalSwitch.Add(10);
            }
            if (globalWorkStepParam.isDischargeCapacityUpperLimitEnabled)
            {
                //uint32_t 放电容量上限bit10
                dataGlobalSwitch.Add(11);
            }
            if (globalWorkStepParam.isVoltageDifferenceEnabled)
            {
                //uint32_t 电压差值bit11
                dataGlobalSwitch.Add(12);
            }
            byteData.AddRange(ConvertIntToByteFlag(dataGlobalSwitch, 4));

            #endregion 全局设定开关

            #region 全局设定数据值

            //uint32_t 数据记录时间值bit0 4   时间值(S)
            byteData.AddRange(IntToByte4(globalWorkStepParam.dataRecordTimeVal));
            //uint32_t 数据记录电压值bit1 4   变化电压值 - bit1
            byteData.AddRange(IntToByte4(globalWorkStepParam.dataRecordVoltageVal));
            //uint32_t 数据记录电流值bit2 4   变化电流值 - bit2
            byteData.AddRange(IntToByte4(globalWorkStepParam.dataRecordCurrentVal));
            //uint32_t 电压上限bit0    4   电压值(V)
            byteData.AddRange(IntToByte4(globalWorkStepParam.voltageUpperLimit));
            //uint32_t 电压下限bit1    4   电压值(V)
            byteData.AddRange(IntToByte4(globalWorkStepParam.voltageLowerLimit));
            //uint32_t 充电电流上限bit2  4   电流值(A)
            byteData.AddRange(IntToByte4(globalWorkStepParam.chargeCurrentUpperLimit));
            //uint32_t 放电电流上限bit3  4   电流值(A)
            byteData.AddRange(IntToByte4(globalWorkStepParam.dischargeCurrentUpperLimit));
            //uint32_t 电池温度上限bit4  4   温度值(℃)
            byteData.AddRange(IntToByte4(globalWorkStepParam.temperatureUpperLimit));
            //uint32_t 电池温度下限bit5  4   温度值(℃)
            byteData.AddRange(IntToByte4(globalWorkStepParam.temperatureLowerLimit));
            //uint32_t 充电容量上限bit6  4   容量值(Ah)
            byteData.AddRange(IntToByte4(globalWorkStepParam.chargeCapacityUpperLimit));
            //uint32_t 放电容量上限bit7  4   容量值(Ah)
            byteData.AddRange(IntToByte4(globalWorkStepParam.dischargeCapacityUpperLimit));
            //uint32_t 电压差值bit10   4   电池电压与第二电压差值 - DelatV(V)
            byteData.AddRange(IntToByte4(globalWorkStepParam.voltageDifference));
            //Arr[] 预留  4x2 预留个字节
            byteData.AddRange(new byte[4 * 2]);

            #endregion 全局设定数据值

            return byteData.ToArray();
        }

        private GlobalWorkStepParam GetGlobalWorkStepData()
        {
            Random random = new Random();
            GlobalWorkStepParam globalWorkStepParam = new GlobalWorkStepParam();
            //uint8_t 数据记录开关  1   每bit对应一种开关，1 - 开，0 - 关
            globalWorkStepParam.isDataRecordTimeValEnabled = true;
            globalWorkStepParam.isDataRecordVoltageValEnabled = false;
            globalWorkStepParam.isDataRecordCurrentValEnabled = true;
            //uint32_t 数据记录时间值bit0 4   时间值(S)
            globalWorkStepParam.dataRecordTimeVal = random.Next(1, 100);
            //uint32_t 数据记录电压值bit1 4   变化电压值 - bit1
            globalWorkStepParam.dataRecordVoltageVal = random.Next(1, 100);
            //uint32_t 数据记录电流值bit2 4   变化电流值 - bit2
            globalWorkStepParam.dataRecordCurrentVal = random.Next(1, 100);
            //uint32_t 全局保护开关  4   每bit对应一种开关，1 - 开，0 - 关
            globalWorkStepParam.isVoltageUpperLimitEnabled = true;
            globalWorkStepParam.isVoltageLowerLimitEnabled = false;
            globalWorkStepParam.isChargeCurrentUpperLimitEnabled = true;
            globalWorkStepParam.isDischargeCurrentUpperLimitEnabled = true;
            globalWorkStepParam.isTemperatureUpperLimitEnabled = true;
            globalWorkStepParam.isTemperatureLowerLimitEnabled = true;
            globalWorkStepParam.isChargeCapacityUpperLimitEnabled = true;
            globalWorkStepParam.isDischargeCapacityUpperLimitEnabled = true;
            //globalWorkStepParam.isChargePowerUpperLimitEnabled = false;
            //globalWorkStepParam.isDischargePowerUpperLimitEnabled = false;
            globalWorkStepParam.isVoltageDifferenceEnabled = true;
            //uint32_t 电压上限bit0    4   电压值(V)
            globalWorkStepParam.voltageUpperLimit = random.Next(1, 100);
            //uint32_t 电压下限bit1    4   电压值(V)
            globalWorkStepParam.voltageLowerLimit = random.Next(1, 100);
            //uint32_t 充电电流上限bit2  4   电流值(A)
            globalWorkStepParam.chargeCurrentUpperLimit = random.Next(1, 100);
            //uint32_t 放电电流上限bit3  4   电流值(A)
            globalWorkStepParam.dischargeCurrentUpperLimit = random.Next(1, 100);
            //uint32_t 电池温度上限bit4  4   温度值(℃)
            globalWorkStepParam.temperatureUpperLimit = random.Next(1, 100);
            //uint32_t 电池温度下限bit5  4   温度值(℃)
            globalWorkStepParam.temperatureLowerLimit = random.Next(1, 100);
            //uint32_t 充电容量上限bit6  4   容量值(Ah)
            globalWorkStepParam.chargeCapacityUpperLimit = random.Next(1, 100);
            //uint32_t 放电容量上限bit7  4   容量值(Ah)
            globalWorkStepParam.dischargeCapacityUpperLimit = random.Next(1, 100);
            ////uint32_t 充电功率上限bit8  4   功率值(W)
            //globalWorkStepParam.chargePowerUpperLimit = random.Next(1, 100);
            ////uint32_t 放电功率上限bit9  4   功率值(W)
            //globalWorkStepParam.dischargePowerUpperLimit = random.Next(1, 100);
            //uint32_t 电压差值bit10   4   电池电压与第二电压差值 - DelatV(V)
            globalWorkStepParam.voltageDifference = random.Next(1, 100);

            return globalWorkStepParam;
        }

        #endregion 回应 读取全局参数

        #region 回应 下发全局参数

        private void GlobalWorkStepDataResponse(int nCommand, byte[] dataBody)
        {
            /********回应数据***************/
            List<byte> commandCode = new List<byte>();
            List<byte> byteData = new List<byte>();
            //命令码
            commandCode.AddRange(MyByteUtil.IntToByte2(nCommand));
            byteData.Add(0x01);
            //添加包头和包尾
            List<byte[]> listRet = AddHeaderAndTail(commandCode.ToArray(), byteData.ToArray());
            if (listRet.Count > 0)
            {
                ChannelManager.GetInstance().SendDataToClient(sci, listRet.First());
            }

            ///反序列化数据
            var globalStepData = DeserializeGlobalStepData(dataBody);
            JsonSerializerSettings settings = new JsonSerializerSettings
            {
                NullValueHandling = NullValueHandling.Include,
                Formatting = Formatting.Indented,
            };
            string strjson = JsonConvert.SerializeObject(globalStepData, settings);
            UseFormShowMsg(strjson);
        }

        #endregion 回应 下发全局参数

        #region 反序列化 全局参数

        private GlobalWorkStepParam DeserializeGlobalStepData(byte[] dataBody)
        {
            GlobalWorkStepParam globalWorkStepParam = new GlobalWorkStepParam();
            //
            if (dataBody.Length < 64)
            {
                return globalWorkStepParam;
            }
            int nIndex = 0;
            byte[] btData = new byte[dataBody.Length];
            Array.Copy(dataBody, 0, btData, 0, btData.Length);
            //uint16_t 校验码 2   工步数据的Crc校验码
            globalWorkStepParam.crcWorkStepParam = new List<byte>() { btData[nIndex++], btData[nIndex++] };
            //uint16_t    工步数量    2   工步数量
            globalWorkStepParam.nWorkStepNum = (int)(btData[nIndex++] | (btData[nIndex++] << 8));

            #region 全局设定开关

            List<int> dataGlobalSwitch = ConvertByteFlagToInt(new byte[4] { btData[nIndex++], btData[nIndex++], btData[nIndex++], btData[nIndex++] });
            //uint32_t 数据记录时间值bit0
            globalWorkStepParam.isDataRecordTimeValEnabled = dataGlobalSwitch.Contains(1);
            //uint32_t 数据记录电压值bit1
            globalWorkStepParam.isDataRecordVoltageValEnabled = dataGlobalSwitch.Contains(2);
            //uint32_t 数据记录电流值bit2
            globalWorkStepParam.isDataRecordCurrentValEnabled = dataGlobalSwitch.Contains(3);
            //uint32_t 电压上限bit3
            globalWorkStepParam.isVoltageUpperLimitEnabled = dataGlobalSwitch.Contains(4);
            //uint32_t 电压下限bit4
            globalWorkStepParam.isVoltageLowerLimitEnabled = dataGlobalSwitch.Contains(5);
            //uint32_t 充电电流上限bit5
            globalWorkStepParam.isChargeCurrentUpperLimitEnabled = dataGlobalSwitch.Contains(6);
            //uint32_t 放电电流上限bit6
            globalWorkStepParam.isDischargeCurrentUpperLimitEnabled = dataGlobalSwitch.Contains(7);
            //uint32_t 电池温度上限bit7
            globalWorkStepParam.isTemperatureUpperLimitEnabled = dataGlobalSwitch.Contains(8);
            //uint32_t 电池温度下限bit8
            globalWorkStepParam.isTemperatureLowerLimitEnabled = dataGlobalSwitch.Contains(9);
            //uint32_t 充电容量上限bit9
            globalWorkStepParam.isChargeCapacityUpperLimitEnabled = dataGlobalSwitch.Contains(10);
            //uint32_t 放电容量上限bit10
            globalWorkStepParam.isDischargeCapacityUpperLimitEnabled = dataGlobalSwitch.Contains(11);
            //uint32_t 电压差值bit11
            globalWorkStepParam.isVoltageDifferenceEnabled = dataGlobalSwitch.Contains(12);

            #endregion 全局设定开关

            #region 全局设定数据值

            //uint32_t 数据记录时间值bit0 4   时间值(S)
            globalWorkStepParam.dataRecordTimeVal = (int)(btData[nIndex++] | (btData[nIndex++] << 8) | (btData[nIndex++] << 16) | (btData[nIndex++] << 24));
            //uint32_t 数据记录电压值bit1 4   变化电压值 - bit1
            globalWorkStepParam.dataRecordVoltageVal = (int)(btData[nIndex++] | (btData[nIndex++] << 8) | (btData[nIndex++] << 16) | (btData[nIndex++] << 24));
            //uint32_t 数据记录电流值bit2 4   变化电流值 - bit2
            globalWorkStepParam.dataRecordCurrentVal = (int)(btData[nIndex++] | (btData[nIndex++] << 8) | (btData[nIndex++] << 16) | (btData[nIndex++] << 24));
            //uint32_t 电压上限bit0    4   电压值(V)
            globalWorkStepParam.voltageUpperLimit = (int)(btData[nIndex++] | (btData[nIndex++] << 8) | (btData[nIndex++] << 16) | (btData[nIndex++] << 24));
            //uint32_t 电压下限bit1    4   电压值(V)
            globalWorkStepParam.voltageLowerLimit = (int)(btData[nIndex++] | (btData[nIndex++] << 8) | (btData[nIndex++] << 16) | (btData[nIndex++] << 24));
            //uint32_t 充电电流上限bit2  4   电流值(A)
            globalWorkStepParam.chargeCurrentUpperLimit = (int)(btData[nIndex++] | (btData[nIndex++] << 8) | (btData[nIndex++] << 16) | (btData[nIndex++] << 24));
            //uint32_t 放电电流上限bit3  4   电流值(A)
            globalWorkStepParam.dischargeCurrentUpperLimit = (int)(btData[nIndex++] | (btData[nIndex++] << 8) | (btData[nIndex++] << 16) | (btData[nIndex++] << 24));
            //uint32_t 电池温度上限bit4  4   温度值(℃)
            globalWorkStepParam.temperatureUpperLimit = (int)(btData[nIndex++] | (btData[nIndex++] << 8) | (btData[nIndex++] << 16) | (btData[nIndex++] << 24));
            //uint32_t 电池温度下限bit5  4   温度值(℃)
            globalWorkStepParam.temperatureLowerLimit = (int)(btData[nIndex++] | (btData[nIndex++] << 8) | (btData[nIndex++] << 16) | (btData[nIndex++] << 24));
            //uint32_t 充电容量上限bit6  4   容量值(Ah)
            globalWorkStepParam.chargeCapacityUpperLimit = (int)(btData[nIndex++] | (btData[nIndex++] << 8) | (btData[nIndex++] << 16) | (btData[nIndex++] << 24));
            //uint32_t 放电容量上限bit7  4   容量值(Ah)
            globalWorkStepParam.dischargeCapacityUpperLimit = (int)(btData[nIndex++] | (btData[nIndex++] << 8) | (btData[nIndex++] << 16) | (btData[nIndex++] << 24));
            //uint32_t 电压差值bit10   4   电池电压与第二电压差值 - DelatV(V)
            globalWorkStepParam.voltageDifference = (int)(btData[nIndex++] | (btData[nIndex++] << 8) | (btData[nIndex++] << 16) | (btData[nIndex++] << 24));

            //Arr[] 预留  2x4 预留 个字节

            #endregion 全局设定数据值

            return globalWorkStepParam;
        }

        #endregion 反序列化 全局参数

        #region 回应 下发工步数据

        /// <summary>
        /// 回应 下发工步数据
        /// </summary>
        /// <param name="nCommand"></param>
        /// <param name="dataBody"></param>
        /// <exception cref="NotImplementedException"></exception>
        private void WorkStepDataResponse(int nCommand, byte[] dataBody)
        {
            /********回应数据***************/
            List<byte> commandCode = new List<byte>();
            List<byte> byteData = new List<byte>();
            //命令码
            commandCode.AddRange(MyByteUtil.IntToByte2(nCommand));
            //返回码	1	0-成功；1-失败//
            byteData.Add(0x01);
            //添加包头和包尾
            List<byte[]> listRet = AddHeaderAndTail(commandCode.ToArray(), byteData.ToArray());
            if (listRet.Count > 0)
            {
                ChannelManager.GetInstance().SendDataToClient(sci, listRet.First());
            }

            ///反序列化数据
            var stepDataList = DeserializeStepData(dataBody);
            JsonSerializerSettings settings = new JsonSerializerSettings
            {
                NullValueHandling = NullValueHandling.Include,
                Formatting = Formatting.Indented,
            };
            string strjson = JsonConvert.SerializeObject(stepDataList, settings);
            // MessageBox.Show(strjson);
            UseFormShowMsg(strjson);
        }

        #endregion 回应 下发工步数据

        #region 反序列化工步数据

        private List<WorkStepDataParam> DeserializeStepData(byte[] dataBody)
        {
            // 假设要反序列化的对象是StepData，反序列化函数名为DeserializeStepData
            // bytes是要反序列化的byte数组
            List<WorkStepDataParam> stepDataList = new List<WorkStepDataParam>();
            if (dataBody.Length <= 8)
            {
                return stepDataList;
            }
            byte[] btData = new byte[dataBody.Length - 8];
            Array.Copy(dataBody, 0, btData, 0, btData.Length);
            int dataLength = 200;
            if (btData.Length % dataLength == 0)
            {
                int dataCount = btData.Length / dataLength;
                for (int i = 0; i < dataCount; i++)
                {
                    int nIndex = 0;
                    byte[] dataBytes = new byte[dataLength];
                    Array.Copy(btData, i * dataLength, dataBytes, 0, dataLength);
                    WorkStepDataParam stepData = new WorkStepDataParam();
                    //uint8_t	工步类型
                    stepData.stepType = Convert.ToInt32(dataBytes[nIndex++]);
                    //uint16_t	工步序号
                    stepData.stepNo = (int)(dataBytes[nIndex++] | (dataBytes[nIndex++] << 8));

                    #region 工步运行主参数

                    /*********工步运行主参数  3*4******************/
                    int[] nMainParam = new int[10];
                    for (int n = 0; n < 3; n++)
                    {
                        nMainParam[n] = (int)(dataBytes[nIndex++] | (dataBytes[nIndex++] << 8) | (dataBytes[nIndex++] << 16) | (dataBytes[nIndex++] << 24));
                    }
                    stepData.stepMainParam = new StepMainParam();
                    stepData.stepMainParam.jumpStepNo = nMainParam[0];
                    stepData.stepMainParam.loopNumber = nMainParam[1];

                    #endregion 工步运行主参数

                    #region 环境控制参数

                    /*********环境控制参数  30******************/
                    stepData.environmentControlParam = new EnvironmentControlParam();
                    //uint8_t 设备类型    1   0 - 无效；1 - 真空控制；2 - 压力控制；3 - 温箱控制；
                    stepData.environmentControlParam.DeviceType = Convert.ToInt32(dataBytes[nIndex++]);
                    //uint8_t 动作类型    1   0 - 无效；
                    //不同设备类型对应不同的动作类型：
                    //真空控制设备: 1 - 关闭；2 - 高真空；3 - 低真空；4 - 微正压
                    //压力控制设备: 1 - 关闭；2 - 压力设置
                    //温箱控制设备: 1 - 关闭；2 - 温度设置
                    stepData.environmentControlParam.ActionType = Convert.ToInt32(dataBytes[nIndex++]);

                    //uint32_t 控制值 4   控制值
                    stepData.environmentControlParam.ControlValue = (int)(dataBytes[nIndex++] | (dataBytes[nIndex++] << 8) | (dataBytes[nIndex++] << 16) | (dataBytes[nIndex++] << 24));
                    //uint32_t 开始时间    4   工步运行到指定时间开始控制,时间值(S)
                    stepData.environmentControlParam.StartTime = (int)(dataBytes[nIndex++] | (dataBytes[nIndex++] << 8) | (dataBytes[nIndex++] << 16) | (dataBytes[nIndex++] << 24));
                    //uint32_t 持续时间    4   控制的总时长，时间值(S)
                    stepData.environmentControlParam.DurationTime = (int)(dataBytes[nIndex++] | (dataBytes[nIndex++] << 8) | (dataBytes[nIndex++] << 16) | (dataBytes[nIndex++] << 24));
                    //uint32_t    预留  4 * 4 预留
                    nIndex += 4 * 4;

                    #endregion 环境控制参数

                    /****************************************/
                    //uint8_t 倍率模式    1
                    stepData.rateMode = Convert.ToInt32(dataBytes[nIndex++]);
                    //uint16_t 标称容量指定工步号   2
                    stepData.nominalCapacityStepNo = (int)(dataBytes[nIndex++] | (dataBytes[nIndex++] << 8));
                    //uint32_t 标称容量    4
                    stepData.nominalCapacity = (int)(dataBytes[nIndex++] | (dataBytes[nIndex++] << 8) | (dataBytes[nIndex++] << 16) | (dataBytes[nIndex++] << 24));

                    #region 工步设定开关

                    /********** 工步设定开关 ***************/
                    //uint32_t	工步设定开关	4	每bit对应一种开关，0-无效；1-开；
                    byte[] btCheckSwitch = new byte[4] { dataBytes[nIndex++], dataBytes[nIndex++], dataBytes[nIndex++], dataBytes[nIndex++] };
                    List<int> checkSwitchFlags = ConvertByteFlagToInt(btCheckSwitch);
                    //截至时间bit0
                    stepData.isCutoffTimeEnabled = checkSwitchFlags.Contains(1);
                    //截至电流bit1
                    stepData.isCutoffCurrentEnabled = checkSwitchFlags.Contains(2);
                    //截至电压bit2
                    stepData.isCutoffVoltageEnabled = checkSwitchFlags.Contains(3);
                    //截至容量bit3
                    stepData.isCutoffCapacityEnabled = checkSwitchFlags.Contains(4);
                    //电压上限bit4    4   电压值(V)
                    stepData.isVoltageUpperLimitEnabled = checkSwitchFlags.Contains(5);
                    //电压下限bit5    4   电压值(V)
                    stepData.isVoltageLowerLimitEnabled = checkSwitchFlags.Contains(6);
                    //电流上限bit6    4   电流值(A)
                    stepData.isCurrentUpperLimitEnabled = checkSwitchFlags.Contains(7);
                    //电流下限bit7    4   电流值(A)
                    stepData.isCurrentLowerLimitEnabled = checkSwitchFlags.Contains(8);
                    //容量上限bit8    4   容量值(Ah)
                    stepData.isCapacityUpperLimitEnabled = checkSwitchFlags.Contains(9);
                    //电池温度上限bit9  4   温度值(℃)
                    stepData.isTemperatureUpperLimitEnabled = checkSwitchFlags.Contains(10);
                    //电池温度下限bit10 4   温度值(℃)
                    stepData.isTemperatureLowerLimitEnabled = checkSwitchFlags.Contains(11);
                    //环境温度上限bit11 4   温度值(℃)
                    stepData.isEnvTemperatureUpperLimitEnabled = checkSwitchFlags.Contains(12);
                    //环境温度下限bit12 4   温度值(℃)
                    stepData.isEnvTemperatureLowerLimitEnabled = checkSwitchFlags.Contains(13);
                    //真空上限bit13   4   真空值(kPa)
                    stepData.isVacuumUpperLimitEnabled = checkSwitchFlags.Contains(14);
                    //真空下限bit14   4   真空值(kPa)
                    stepData.isVacuumLowerLimitEnabled = checkSwitchFlags.Contains(15);
                    //电池温度变化率bit15    10  参考变化率数据结构
                    stepData.isBatteryTemperatureChangeRateEnabled = checkSwitchFlags.Contains(16);
                    //电压变化率bit16  10  参考变化率数据结构
                    stepData.isVoltageChangeRateEnabled = checkSwitchFlags.Contains(17);
                    //其他类型变化率bit17    1   变化率类型 预留
                    stepData.isOtherChangeRateEnabled = checkSwitchFlags.Contains(18);
                    //指定时间内电压bit18    4   指定时间值(S)
                    stepData.isVoltageInTimePeriodEnabled = checkSwitchFlags.Contains(19);

                    #endregion 工步设定开关

                    #region 工步开关数据值

                    //uint8_t 条件达到动作类型    1   0 - 下一步， 1 - 停止，2 - 结束
                    stepData.conditionMetActionType = Convert.ToInt32(dataBytes[nIndex++]);
                    //uint32_t 截至时间bit0    4   时间值(S)
                    stepData.cutoffTime = (int)(dataBytes[nIndex++] | (dataBytes[nIndex++] << 8) | (dataBytes[nIndex++] << 16) | (dataBytes[nIndex++] << 24));
                    //uint32_t 截至电流bit1    4   电流值(A)
                    stepData.cutoffCurrent = (int)(dataBytes[nIndex++] | (dataBytes[nIndex++] << 8) | (dataBytes[nIndex++] << 16) | (dataBytes[nIndex++] << 24));
                    //uint32_t 截至电压bit2    4   电压值(V)
                    stepData.cutoffVoltage = (int)(dataBytes[nIndex++] | (dataBytes[nIndex++] << 8) | (dataBytes[nIndex++] << 16) | (dataBytes[nIndex++] << 24));
                    //uint32_t 截至容量bit3    4   容量值(Ah)
                    stepData.cutoffCapacity = (int)(dataBytes[nIndex++] | (dataBytes[nIndex++] << 8) | (dataBytes[nIndex++] << 16) | (dataBytes[nIndex++] << 24));
                    //uint32_t 电压上限bit0    4   电压值(V)
                    stepData.voltageUpperLimit = (int)(dataBytes[nIndex++] | (dataBytes[nIndex++] << 8) | (dataBytes[nIndex++] << 16) | (dataBytes[nIndex++] << 24));
                    //uint32_t 电压下限bit1    4   电压值(V)
                    stepData.voltageLowerLimit = (int)(dataBytes[nIndex++] | (dataBytes[nIndex++] << 8) | (dataBytes[nIndex++] << 16) | (dataBytes[nIndex++] << 24));
                    //uint32_t 电流上限bit2    4   电流值(A)
                    stepData.currentUpperLimit = (int)(dataBytes[nIndex++] | (dataBytes[nIndex++] << 8) | (dataBytes[nIndex++] << 16) | (dataBytes[nIndex++] << 24));
                    //uint32_t 电流下限bit3    4   电流值(A)
                    stepData.currentLowerLimit = (int)(dataBytes[nIndex++] | (dataBytes[nIndex++] << 8) | (dataBytes[nIndex++] << 16) | (dataBytes[nIndex++] << 24));
                    //uint32_t 容量上限bit4    4   容量值(Ah)
                    stepData.capacityUpperLimit = (int)(dataBytes[nIndex++] | (dataBytes[nIndex++] << 8) | (dataBytes[nIndex++] << 16) | (dataBytes[nIndex++] << 24));
                    //uint32_t 电池温度上限bit6  4   温度值(℃)
                    stepData.temperatureUpperLimit = (int)(dataBytes[nIndex++] | (dataBytes[nIndex++] << 8) | (dataBytes[nIndex++] << 16) | (dataBytes[nIndex++] << 24));
                    //uint32_t 电池温度下限bit7  4   温度值(℃)
                    stepData.temperatureLowerLimit = (int)(dataBytes[nIndex++] | (dataBytes[nIndex++] << 8) | (dataBytes[nIndex++] << 16) | (dataBytes[nIndex++] << 24));
                    //uint32_t 环境温度上限bit8  4   温度值(℃)
                    stepData.envTemperatureUpperLimit = (int)(dataBytes[nIndex++] | (dataBytes[nIndex++] << 8) | (dataBytes[nIndex++] << 16) | (dataBytes[nIndex++] << 24));
                    //uint32_t 环境温度下限bit9  4   温度值(℃)
                    stepData.envTemperatureLowerLimit = (int)(dataBytes[nIndex++] | (dataBytes[nIndex++] << 8) | (dataBytes[nIndex++] << 16) | (dataBytes[nIndex++] << 24));
                    //uint32_t 真空上限bit10   4   真空值(kPa)
                    stepData.vacuumUpperLimit = (int)(dataBytes[nIndex++] | (dataBytes[nIndex++] << 8) | (dataBytes[nIndex++] << 16) | (dataBytes[nIndex++] << 24));
                    //uint32_t 真空下限bit11   4   真空值(kPa)
                    stepData.vacuumLowerLimit = (int)(dataBytes[nIndex++] | (dataBytes[nIndex++] << 8) | (dataBytes[nIndex++] << 16) | (dataBytes[nIndex++] << 24));
                    /*********Null 电池温度变化率bit12    10  参考变化率数据结构**********/
                    stepData.batteryTemperatureChangeRate = new RateChangeData();
                    //uint8_t 比较类型    1   0：≥； 1： ≤;
                    stepData.batteryTemperatureChangeRate.CompareType = Convert.ToInt32(dataBytes[nIndex++]);
                    //uint8_t 比较次数    1   范围1 - 255
                    stepData.batteryTemperatureChangeRate.CompareCount = Convert.ToInt32(dataBytes[nIndex++]);
                    //uint32_t 比较绝对值   4   比较值
                    stepData.batteryTemperatureChangeRate.CompareValue = (int)(dataBytes[nIndex++] | (dataBytes[nIndex++] << 8) | (dataBytes[nIndex++] << 16) | (dataBytes[nIndex++] << 24));
                    //uint32_t    比较间隔时间  4   间隔时间
                    stepData.batteryTemperatureChangeRate.CompareInterval = (int)(dataBytes[nIndex++] | (dataBytes[nIndex++] << 8) | (dataBytes[nIndex++] << 16) | (dataBytes[nIndex++] << 24));

                    /*********Null    电压变化率bit13  10  参考变化率数据结构**********/
                    stepData.voltageChangeRate = new RateChangeData();
                    //uint8_t 比较类型    1   0：≥； 1： ≤;
                    stepData.voltageChangeRate.CompareType = Convert.ToInt32(dataBytes[nIndex++]);
                    //uint8_t 比较次数    1   范围1 - 255
                    stepData.voltageChangeRate.CompareCount = Convert.ToInt32(dataBytes[nIndex++]);
                    //uint32_t 比较绝对值   4   比较值
                    stepData.voltageChangeRate.CompareValue = (int)(dataBytes[nIndex++] | (dataBytes[nIndex++] << 8) | (dataBytes[nIndex++] << 16) | (dataBytes[nIndex++] << 24));
                    //uint32_t    比较间隔时间  4   间隔时间
                    stepData.voltageChangeRate.CompareInterval = (int)(dataBytes[nIndex++] | (dataBytes[nIndex++] << 8) | (dataBytes[nIndex++] << 16) | (dataBytes[nIndex++] << 24));

                    //Uint8_t 其他类型变化率bit15    1   变化率类型 预留
                    byte btotherRate = dataBytes[nIndex++];
                    /*********Null 其他类型变化率bit15    10  参考变化率数据结构**********/
                    stepData.otherChangeRate = new RateChangeData();
                    //uint8_t 比较类型    1   0：≥； 1： ≤;
                    stepData.otherChangeRate.CompareType = Convert.ToInt32(dataBytes[nIndex++]);
                    //uint8_t 比较次数    1   范围1 - 255
                    stepData.otherChangeRate.CompareCount = Convert.ToInt32(dataBytes[nIndex++]);
                    //uint32_t 比较绝对值   4   比较值
                    stepData.otherChangeRate.CompareValue = (int)(dataBytes[nIndex++] | (dataBytes[nIndex++] << 8) | (dataBytes[nIndex++] << 16) | (dataBytes[nIndex++] << 24));
                    //uint32_t    比较间隔时间  4   间隔时间
                    stepData.otherChangeRate.CompareInterval = (int)(dataBytes[nIndex++] | (dataBytes[nIndex++] << 8) | (dataBytes[nIndex++] << 16) | (dataBytes[nIndex++] << 24));

                    //uint32_t    指定时间内电压bit16    4   指定时间值
                    stepData.voltageInTimePeriod = (int)(dataBytes[nIndex++] | (dataBytes[nIndex++] << 8) | (dataBytes[nIndex++] << 16) | (dataBytes[nIndex++] << 24));
                    //uint32_t    时间内电压最大值bit16   4   指定时间内电压最大值
                    stepData.maxVoltageInTimePeriod = (int)(dataBytes[nIndex++] | (dataBytes[nIndex++] << 8) | (dataBytes[nIndex++] << 16) | (dataBytes[nIndex++] << 24));
                    //uint32_t    时间内电压最小值bit16   4   指定时间内电压最小值
                    stepData.minVoltageInTimePeriod = (int)(dataBytes[nIndex++] | (dataBytes[nIndex++] << 8) | (dataBytes[nIndex++] << 16) | (dataBytes[nIndex++] << 24));
                    //Null    预留 10 * 4    预留

                    #endregion 工步开关数据值

                    stepDataList.Add(stepData);
                }
            }
            return stepDataList;
        }

        #endregion 反序列化工步数据

        #region 简单回应,带有通道

        /// <summary>
        /// 简单回应: 命令码、通道 、返回码	1	0-成功；1-失败
        /// </summary>
        /// <param name="nCommand"></param>
        /// <param name="dataBody"></param>
        /// <exception cref="NotImplementedException"></exception>
        private void SimpleWithChannelResponse(int nCommand, byte[] dataBody)
        {
            List<byte> commandCode = new List<byte>();
            List<byte> byteData = new List<byte>();
            //命令码
            commandCode.AddRange(MyByteUtil.IntToByte2(nCommand));
            //通道
            byteData.Add(dataBody[0]); byteData.Add(dataBody[1]);
            //返回码
            byteData.Add(0x01);
            //添加包头和包尾
            List<byte[]> listRet = AddHeaderAndTail(commandCode.ToArray(), byteData.ToArray());
            if (listRet.Count > 0)
            {
                ChannelManager.GetInstance().SendDataToClient(sci, listRet.First());
            }
        }

        #endregion 简单回应,带有通道

        #region ___回应心跳___

        /// <summary>
        /// 生命帧回应
        /// </summary>
        private void LifeFrameResponse(int nCommand, byte[] dataBody)
        {
            List<byte> commandCode = new List<byte>();
            List<byte> byteData = new List<byte>();
            //命令码
            commandCode.AddRange(MyByteUtil.IntToByte2(nCommand));
            //同步码	4	回复接收到的同步码
            byteData.AddRange(dataBody);
            //添加包头和包尾
            List<byte[]> listRet = AddHeaderAndTail(commandCode.ToArray(), byteData.ToArray());
            if (listRet.Count > 0)
            {
                ChannelManager.GetInstance().SendDataToClient(sci, listRet.First());
            }
        }

        #endregion ___回应心跳___

        #region ___简单回应___

        /// <summary>
        /// 简单回应: 命令码 、返回码	1	0-成功；1-失败
        /// </summary>
        /// <returns></returns>
        public void SimpleResponse(int nCommand, byte[] dataBody)
        {
            List<byte> commandCode = new List<byte>();
            List<byte> byteData = new List<byte>();
            //命令码
            commandCode.AddRange(MyByteUtil.IntToByte2(nCommand));
            //返回码	1	0-成功；1-失败
            byteData.Add(0x00);
            if (nCommand == 8193 || nCommand == 8194)
            {
                //运行 8193
                //停止 8194
                byteData.AddRange(new byte[10]);
            }
            //添加包头和包尾
            List<byte[]> listRet = AddHeaderAndTail(commandCode.ToArray(), byteData.ToArray());
            if (listRet.Count > 0)
            {
                ChannelManager.GetInstance().SendDataToClient(sci, listRet.First());
            }
        }

        #endregion ___简单回应___

        #region ___包头、包尾___

        /// <summary>
        /// 3.1包头
        //名称 长度  描述
        //起始码	4个字节	0xAC 0xFD 0xFD 0xAC
        //长度	    2个字节 包体的长度
        //版本号	2个字节 协议版本号
        //校验码	2个字节 Crc16校验码(包体的数据校验)
        //序列号	1个字节 用于区分连续相同的包，相邻两包之间不相等
        //总包数	1个字节 总包数
        //当前包序号	1个字节 当前包序号

        //包尾	2个字节	0xFE 0xFE
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        private List<byte[]> AddHeaderAndTail(byte[] commandCode, byte[] data)
        {
            /************data拆分为List<byte[]>  每个byte[]最长为65520***********************/
            int maxChunkSize = 8000; // 每个字节数组最大长度 8*1000
            List<byte[]> result = new List<byte[]>(); // 存储结果的字节数组集合
            int offset = 0; // 记录当前处理的字节数组在输入数据中的偏移量
            while (offset < data.Length)
            {
                int chunkSize = Math.Min(maxChunkSize, data.Length - offset); // 计算当前处理的字节数组的长度
                byte[] chunk = new byte[chunkSize]; // 创建当前处理的字节数组
                Array.Copy(data, offset, chunk, 0, chunkSize); // 将输入数据中的一段拷贝到当前处理的字节数组中
                result.Add(chunk); // 将当前处理的字节数组加入结果集合中
                offset += chunkSize; // 更新偏移量
            }
            /******************为List<byte[]> 每一项添加包头和包尾**************************************************************/
            List<byte[]> dataArray = new List<byte[]>();
            byte btPackOrder = getRandom();
            int nCurrentIndex = -1;
            foreach (byte[] item in result)
            {
                /*************添加包头***********/
                List<byte> byteData = new List<byte>();
                //起始码4个字节
                byteData.Add(0xAC); byteData.Add(0xFD); byteData.Add(0xFD); byteData.Add(0xAC);
                //版本号 2个字节
                byteData.Add(0x01); byteData.Add(0x00);
                //序列号 1个字节 用于区分连续相同的包，相邻两包之间不相等
                byteData.Add(btPackOrder);
                //总包数 1个字节
                byteData.Add(Convert.ToByte(result.Count & 0xFF));
                //当前包序号	1个字节 当前包序号 从0开始
                nCurrentIndex++;
                byteData.Add(Convert.ToByte(nCurrentIndex & 0xFF));
                //命令码 2个字节
                byteData.AddRange(commandCode);
                //长度 2个字节  包体和包尾的长度(每包建议下发长度最大不超过8*1024)
                byteData.AddRange(IntToByte2(item.Length + 2).ToArray());
                //添加包体
                byteData.AddRange(item);
                //添加包体 结束码	2个字节	Crc16校验码，包头和包体的数据校验码
                byteData.AddRange(Crc16(byteData.ToArray()).ToArray());
                dataArray.Add(byteData.ToArray());
            }
            return dataArray;
        }

        /// <summary>
        /// 获取一个和上次不一样的随机数
        /// </summary>
        /// <returns></returns>
        //随机数（包头--序列号	1个字节	用于区分连续相同的包，相邻两包之间不相等）
        private byte lastRandomByte = 0;

        private byte getRandom()
        {
            Random random = new Random(DateTime.Now.Millisecond);
            for (int i = 0; i < 10; i++)
            {
                byte randomByte;
                do
                {
                    randomByte = (byte)random.Next(255);
                } while (randomByte == lastRandomByte); // 重试直到生成一个不同的随机数

                lastRandomByte = randomByte;
                //Console.WriteLine($"Generated random byte: {randomByte}");
            }
            return lastRandomByte;
        }

        #endregion ___包头、包尾___

        #region ___发送实时数据___

        /// <summary>
        /// 发送实时数据
        /// </summary>
        /// <param name="numberOfData"></param>
        public void SendRealData(int numberOfData)
        {
            List<RealTimeSampleData> realTimeSampleDatas;
            //实时数据 numberOfData条数据
            List<byte[]> listRet = GetRealData(numberOfData, out realTimeSampleDatas);
            if (listRet.Count > 0)
            {
                ChannelManager.GetInstance().SendDataToAllClient(listRet.First());
            }
            //JsonSerializerSettings settings = new JsonSerializerSettings
            //{
            //    NullValueHandling = NullValueHandling.Include,
            //    Formatting = Formatting.Indented,
            //};
            //string strjson = JsonConvert.SerializeObject(realTimeSampleDatas, settings);
            //UseFormShowMsg(strjson);
        }

        /// <summary>
        /// 获取实时数据
        /// </summary>
        /// <param name="numberOfData">数据条数</param>
        /// <returns></returns>
        public List<byte[]> GetRealData(int numberOfData, out List<RealTimeSampleData> realTimeSampleDatas)
        {
            List<byte> commandCode = new List<byte>();
            List<byte> byteData = new List<byte>();
            //命令码	2	0x4000
            commandCode.Add(00); commandCode.Add(0x40);
            //数据条数    2   本包数据实时数据的条数
            byteData.AddRange(MyByteUtil.IntToByte2(numberOfData));
            //通道实时数据  N 参考通道实时数据结构
            realTimeSampleDatas = GetRealTimeSampleData(numberOfData);
            byteData.AddRange(SerializeRealData(realTimeSampleDatas));

            //添加包头和包尾
            List<byte[]> listRet = AddHeaderAndTail(commandCode.ToArray(), byteData.ToArray());
            return listRet;
        }

        /// <summary>
        /// 组件实时数据
        /// </summary>
        /// <param name="numberOfData"></param>
        /// <returns></returns>
        private List<RealTimeSampleData> GetRealTimeSampleData(int numberOfData)
        {
            Random random = new Random(DateTime.Now.Millisecond);
            List<RealTimeSampleData> realDataList = new List<RealTimeSampleData>();
            for (int n = 0; n < numberOfData; n++)
            {
                RealTimeSampleData realTimeSampleData = new RealTimeSampleData();
                //Uint8_t 工步类型    1   参考工步类型数据结构
                realTimeSampleData.stepType = random.Next(1, 10);
                //Uint8_t 运行状态    1   运行状态 0-5
                realTimeSampleData.runState = random.Next(0, 7);
                //Uint16_t    通道号 2   通道号
                realTimeSampleData.channel = n + 1;
                //Uint16_t    工步序号    2   工步序号
                realTimeSampleData.stepNo = random.Next(1, 10);
                //Uint16_t    当前循环号   2   当前循环正在执行的循环号
                realTimeSampleData.loopIndex = random.Next(1, 10);
                //Uint16_t    当前循环总次数 2   当前循环需要执行的总次数
                realTimeSampleData.loopCount = random.Next(1, 10);
                //uint32_t    运行时间    4   当前工步运行时间 *1000 [1秒到8秒)
                realTimeSampleData.runTime = random.Next(1000, 800000);
                //uint32_t    电池电压    4   电压值(V) *10000  [1v到30v)
                realTimeSampleData.batteryVoltage = random.Next(10000, 300000);
                //uint32_t 电压2 4   电压值(V)
                realTimeSampleData.voltage2 = random.Next(10000, 300000);
                //uint32_t 通道电流    4   电流值(A)
                realTimeSampleData.channelCurrent = random.Next(10000, 60000);
                //Uint16_t 电池温度1   4   温度值(℃)
                realTimeSampleData.batteryTemperature1 = random.Next(10, 900);
                //Uint16_t 电池温度2   4   温度值(℃)
                realTimeSampleData.batteryTemperature2 = random.Next(10, 900);
                //uint32_t 实时容量    4   容量值(Ah)   [1AH,200AH)
                realTimeSampleData.realTimeCapacity = random.Next(10000, 2000000);
                //uint32_t 实时能量    4   能量值
                realTimeSampleData.realTimeEnergy = random.Next(10000, 2000000);
                //uint32_t    直流内阻    4   内阻值   *1000
                realTimeSampleData.dcInnerResistance = random.Next(1000, 100000);
                //uint32_t    接触阻抗    2   接触阻抗值
                realTimeSampleData.contactResistance = random.Next(1000, 100000);
                //Uint16_t    环境温度1   2   温度值(℃)
                realTimeSampleData.environmentTemperature1 = random.Next(10, 900);
                //Uint16_t    环境温度2   2   温度值(℃)
                realTimeSampleData.environmentTemperature2 = random.Next(10, 900);
                //Uint16_t    火警温度    2   温度值(℃)
                realTimeSampleData.fireAlarmTemperature = random.Next(10, 900);
                //uint32_t    环境值 4	//真空压力或其它环境参数值
                realTimeSampleData.environmentVal = random.Next(30, 300);
                //uint16_t    错误码 2   错误码
                realTimeSampleData.errorCode = CommonConfig.ErrcodeArray[random.Next(0, CommonConfig.ErrcodeArray.Count())];
                //Uint64_t    电源告警码   8   电源告警码
                realTimeSampleData.powerAlarmCode = random.NextInt64(8000, 90000);
                //uint32_t    预留  8x4 预留

                realDataList.Add(realTimeSampleData);
            }
            return realDataList;
        }

        /// <summary>
        /// 实时数据转二进制
        /// </summary>
        /// <param name="realTimeSampleDatas"></param>
        /// <returns></returns>
        private byte[] SerializeRealData(List<RealTimeSampleData> realTimeSampleDatas)
        {
            Random random = new Random();
            List<byte> byteData = new List<byte>();
            foreach (RealTimeSampleData realTimeSampleData in realTimeSampleDatas)
            {
                //1   Uint8_t 工步类型      1   参考工步类型数据结构
                byteData.Add(Convert.ToByte(realTimeSampleData.stepType & 0xFF));
                //2   Uint8_t 运行状态      1   运行状态
                byteData.Add(Convert.ToByte(realTimeSampleData.runState & 0xFF));
                //3   Uint16_t 通道号       2   通道号
                byteData.AddRange(IntToByte2(realTimeSampleData.channel));
                //4   Uint16_t 工步序号     2   工步序号
                byteData.AddRange(IntToByte2(realTimeSampleData.stepNo));
                //5   Uint16_t 当前循环号   2   当前循环正在执行的循环号
                byteData.AddRange(IntToByte2(realTimeSampleData.loopIndex));
                //6   Uint16_t 当前循环总次数 2   当前循环需要执行的总次数
                byteData.AddRange(IntToByte2(realTimeSampleData.loopCount));
                //7   uint32_t 运行时间    4   当前工步运行时间
                byteData.AddRange(IntToByte4(realTimeSampleData.runTime));
                //8   uint32_t 电池电压    4   电压值(V)
                byteData.AddRange(IntToByte4(realTimeSampleData.batteryVoltage));
                //9   uint32_t 电压2 4   电压值(V)
                byteData.AddRange(IntToByte4(realTimeSampleData.voltage2));
                //10  uint32_t 通道电流    4   电流值(A)
                byteData.AddRange(IntToByte4(realTimeSampleData.channelCurrent));
                //11  Uint16_t 电池温度1   2   温度值(℃)
                byteData.AddRange(IntToByte2(realTimeSampleData.batteryTemperature1));
                //12  Uint16_t 电池温度2   2   温度值(℃)
                byteData.AddRange(IntToByte2(realTimeSampleData.batteryTemperature2));
                //13  uint32_t 实时容量    4   容量值(Ah)
                byteData.AddRange(IntToByte4(realTimeSampleData.realTimeCapacity));
                //14  uint32_t 实时能量    4   能量值
                byteData.AddRange(IntToByte4(realTimeSampleData.realTimeEnergy));
                //15  uint32_t 直流内阻    4   内阻值
                byteData.AddRange(IntToByte4(realTimeSampleData.dcInnerResistance));
                //16  uint32_t 接触阻抗    4   接触阻抗值
                byteData.AddRange(IntToByte4(realTimeSampleData.contactResistance));

                //17  Uint16_t 环境温度1   2   温度值(℃)
                byteData.AddRange(IntToByte2(realTimeSampleData.environmentTemperature1));
                //18  Uint16_t 环境温度2   2   温度值(℃)
                byteData.AddRange(IntToByte2(realTimeSampleData.environmentTemperature2));
                //19  Uint16_t 火警温度    2   温度值(℃)
                byteData.AddRange(IntToByte2(realTimeSampleData.fireAlarmTemperature));
                //20  uint32_t 环境值 4	//真空压力或其它环境参数值
                byteData.AddRange(IntToByte4(realTimeSampleData.environmentVal));
                //21  uint16_t 错误码 2   错误码
                byteData.AddRange(IntToByte2(realTimeSampleData.errorCode));
                //22  Uint64_t 电源告警码   8   电源告警码
                byte[] bytes = BitConverter.GetBytes(realTimeSampleData.powerAlarmCode);
                if (!BitConverter.IsLittleEndian)
                    Array.Reverse(bytes);

                byteData.AddRange(bytes);
                //23  uint32_t 预留  4x4 预留
                byteData.AddRange(new byte[4 * 4]);
            }
            return byteData.ToArray();
        }

        #endregion ___发送实时数据___

        #region ___发送一条历史数据___

        /// <summary>
        /// 发送历史数据
        /// </summary>
        /// <param name="numberOfData"></param>
        public void SendHistoryData(int numberOfData)
        {
            List<HistorySampleData> historySampleDatas;
            //模拟历史数据
            List<byte[]> listRet = GetHistoryData(numberOfData, out historySampleDatas);
            if (listRet.Count > 0)
            {
                ChannelManager.GetInstance().SendDataToAllClient(listRet.First());
            }
            JsonSerializerSettings settings = new JsonSerializerSettings
            {
                NullValueHandling = NullValueHandling.Include,
                Formatting = Formatting.Indented,
            };
            string strjson = JsonConvert.SerializeObject(historySampleDatas, settings);
            UseFormShowMsg(strjson);
        }

        /// <summary>
        /// 历史数据转二进制
        /// </summary>
        /// <param name="numberOfData"></param>
        /// <param name="historySampleDatas"></param>
        /// <returns></returns>
        private List<byte[]> GetHistoryData(int numberOfData, out List<HistorySampleData> historySampleDatas)
        {
            List<byte> commandCode = new List<byte>();
            List<byte> byteData = new List<byte>();
            //命令码	2	0x5000
            commandCode.Add(00); commandCode.Add(0x50);
            //历史数据条数    2   本包数据实时数据的条数
            byteData.AddRange(MyByteUtil.IntToByte2(numberOfData));
            //历史数据	N	参考历史数据结构
            historySampleDatas = GetHistorySampleData(numberOfData);
            //包体
            byteData.AddRange(SerializeHistoryData(historySampleDatas));

            //添加包头和包尾
            List<byte[]> listRet = AddHeaderAndTail(commandCode.ToArray(), byteData.ToArray());
            return listRet;
        }

        /// <summary>
        /// 获取历史数据
        /// </summary>
        /// <param name="numberOfData"></param>
        /// <returns></returns>
        private List<HistorySampleData> GetHistorySampleData(int numberOfData)
        {
            Random random = new Random();
            List<HistorySampleData> historyDataList = new List<HistorySampleData>();
            for (int n = 0; n < numberOfData; n++)
            {
                HistorySampleData historySampleData = new HistorySampleData();
                //1   Uint8_t 工步类型    1   参考工步类型数据结构
                historySampleData.stepType = random.Next(1, 10);
                //2   Uint8_t 事件码 2   事件码
                historySampleData.eventCode = random.Next(1, 10);
                //3   Uint16_t 通道号 2   通道号
                historySampleData.channel = n + 1;
                // UUID	4 每个通道固定UUID
                historySampleData.UUID = BitConverter.ToUInt32(Guid.NewGuid().ToByteArray(), 0);
                //4   Uint16_t 工步序号    2   工步序号
                historySampleData.stepNo = random.Next(1, 10);
                //5   Uint16_t 当前循环号   2   当前循环正在执行的循环号
                historySampleData.loopIndex = random.Next(1, 10);
                //6   Uint32_t 步次号 4   从1开始，每执行一个工步递增1
                historySampleData.stepOrder = random.Next(1, 10);
                //7   uint32_t 数据记录索引  4   数据记录索引,从1开始，每记录一条 + 1
                historySampleData.dataRecordIndex = random.Next(1, 500);
                //8   uint32_t 运行时间    4   当前工步运行时间值 ms
                historySampleData.runTime = random.Next(1000, 888000);
                //9   uint32_t 绝对时间    4   Unix时间
                DateTime now = DateTime.Now;
                STLocTime stLocTime = new STLocTime();
                stLocTime.Seconds = (uint)now.Second;
                stLocTime.Minutes = (uint)now.Minute;
                stLocTime.Hours = (uint)now.Hour;
                stLocTime.Day = (uint)now.Day;
                stLocTime.Month = (uint)now.Month;
                stLocTime.Year = ((uint)(now.Year % 2000));

                historySampleData.absoluteTime = stLocTime.uiLoTime;
                //10  uint32_t 电池电压    4   电压值（V）
                historySampleData.batteryVoltage = random.Next(10000, 300000);
                //11  uint32_t 电压2 4   电压值（V）
                historySampleData.voltage2 = random.Next(10000, 300000);
                //12  uint32_t 通道电流    4   电流值(A)
                historySampleData.channelCurrent = random.Next(10000, 300000);
                //13  uint32_t 电池温度1   4   温度值(℃)
                historySampleData.batteryTemperature1 = random.Next(10, 900);
                //14  uint32_t 电池温度2   4   温度值(℃)
                historySampleData.batteryTemperature2 = random.Next(10, 900);
                //15  uint32_t 容量  4   容量值(Ah)
                historySampleData.realTimeCapacity = random.Next(10000, 2000000);
                //16  uint32_t 能量  4   能量值
                historySampleData.realTimeEnergy = random.Next(10000, 2000000);
                //17  uint32_t 直流内阻    4   内阻值
                historySampleData.dcInnerResistance = random.Next(1000, 100000);
                //18  uint32_t 接触阻抗    4   接触阻抗值
                historySampleData.contactResistance = random.Next(1000, 100000);
                //19  Uint16_t 环境温度1   2   温度值(℃)
                historySampleData.environmentTemperature1 = random.Next(10, 900);
                //20  Uint16_t 环境温度2   2   温度值(℃)
                historySampleData.environmentTemperature2 = random.Next(10, 900);
                //23  Uint16_t 火警温度    2   温度值(℃)
                historySampleData.fireAlarmTemperature = random.Next(10, 900);
                //24  uint32_t 环境值 4	//真空压力或其它环境参数值
                historySampleData.environmentVal = random.Next(10, 900);
                //25  uint32_t 预留  10x4 预留
                historyDataList.Add(historySampleData);
            }
            return historyDataList;
        }

        #endregion ___发送一条历史数据___

        #region ___模拟历史数据___

        private Dictionary<int, UInt32> testUuidMap = new Dictionary<int, UInt32>();
        private Dictionary<int, int> recordIndexMap = new Dictionary<int, int>();

        /// <summary>
        /// 发送模拟历史数据
        /// </summary>
        /// <param name="nCheckNum"></param>
        /// <param name="nLoopNum"></param>
        /// <param name="stepItems"></param>
        /// <param name="nDataNum"></param>
        /// <param name="channelNum"></param>
        /// <param name="nSamplingInterval"></param>
        /// <param name="ntextBoxBatchSize"></param>
        public void SendSimulatedHistoryData(int nCheckNum, int nLoopNum, List<StepType> stepItems, int nDataNum, int channelNum, int nSamplingInterval, int ntextBoxBatchSize)
        {
            int nGenerateDataInterval = 1000;
            activateSignal.Reset();
            historyCacheQueue.Clear();
            List<byte> commandCode = new List<byte>();
            //命令码	2	0x5000
            commandCode.Add(00); commandCode.Add(0x50);

            int nRecordIndex = 0;
            int runTime = 0;
            //测试次数
            for (int n = 0; n < nCheckNum; n++)
            {
                //清空字典
                testUuidMap.Clear();
                recordIndexMap.Clear();
                //通道数量
                for (int k = 1; k <= channelNum; k++)
                {
                    //UUID字典
                    testUuidMap[k] = BitConverter.ToUInt32(Guid.NewGuid().ToByteArray(), 0);
                    recordIndexMap[k] = 0;
                }
                //循环次数
                for (int loopNum = 1; loopNum <= nLoopNum; loopNum++)
                {
                    //工步数量
                    for (int nStepOrder = 0; nStepOrder < stepItems.Count; nStepOrder++)
                    {
                        runTime = 0;
                        //每个工步的包数
                        for (int j = 1; j <= nDataNum; j++)
                        {
                            nRecordIndex++;
                            int batchSize = ntextBoxBatchSize;
                            if (batchSize > 70)
                            {
                                batchSize = 70;
                            }
                            for (int bi = 1; bi <= channelNum; bi += batchSize)
                            {
                                int bj = Math.Min(bi + batchSize - 1, channelNum);

                                if ((historyCacheQueue.Count() + (bj - bi + 1)) <= 70)
                                {
                                    //缓存数据条数+即将生成的数据条数 小于等于70  可以继续生产
                                    List<HistorySampleData> historySampleDatas = GetHistorySimulatedData(bi, bj, nStepOrder, stepItems[nStepOrder], loopNum, runTime);
                                    historyCacheQueue.AddRange(historySampleDatas);
                                }
                                else
                                {

                                    while (historyCacheQueue.Count >= 70)
                                    {
                                        //缓存数据条数超过70了，等待缓存清掉
                                        SendhistoryCacheData();
                                        activateSignal.WaitOne(nGenerateDataInterval);
                                    }
                                    List<HistorySampleData> historySampleDatas = GetHistorySimulatedData(bi, bj, nStepOrder, stepItems[nStepOrder], loopNum, runTime);
                                    historyCacheQueue.AddRange(historySampleDatas);

                                }
                                if (historyCacheQueue.Count > 0)
                                {
                                    SendhistoryCacheData();
                                    activateSignal.WaitOne(nGenerateDataInterval);
                                }

                                #region 模拟‘上位机’不回复时蔽掉
                                //List<byte> byteData = new List<byte>();

                                ////历史数据条数    2   本包数据实时数据的条数
                                //byteData.AddRange(MyByteUtil.IntToByte2(channelNum));
                                ////历史数据	N	参考历史数据结构
                                //List<HistorySampleData> historySampleDatas = GetHistorySimulatedData(bi, bj, nStepOrder, stepItems[nStepOrder], loopNum, runTime);
                                //byteData.AddRange(SerializeHistoryData(historySampleDatas));

                                ////添加包头和包尾
                                //List<byte[]> listRet = AddHeaderAndTail(commandCode.ToArray(), byteData.ToArray());
                                //foreach (byte[] bt in listRet)
                                //{

                                //    ChannelManager.GetInstance().SendDataToAllClient(bt);
                                //}
                                #endregion
                                //Task.Delay(2).Wait();
                            }
                            //Task.Delay(2).Wait();

                            //相对时间间隔
                            runTime += nSamplingInterval;
                        }
                    }
                }
            }
        }
        private void SendhistoryCacheData()
        {
            //bug集合被修改
            lock (lockobj)
            {
                List<byte> commandCode = new List<byte>();
                //命令码	2	0x5000
                commandCode.Add(00); commandCode.Add(0x50);
                List<byte> byteData = new List<byte>();

                //历史数据条数    2   本包数据实时数据的条数
                byteData.AddRange(MyByteUtil.IntToByte2(historyCacheQueue.Count()));

                byteData.AddRange(SerializeHistoryData(historyCacheQueue));
                //添加包头和包尾
                List<byte[]> listRet = AddHeaderAndTail(commandCode.ToArray(), byteData.ToArray());
                foreach (byte[] bt in listRet)
                {
                    ChannelManager.GetInstance().SendDataToAllClient(bt);
                }
            }


        }
        /// <summary>
        /// 构建历史数据
        /// </summary>
        /// <param name="channelNumStart"></param>
        /// <param name="channelNumEnd"></param>
        /// <param name="nStepOrder"></param>
        /// <param name="stepType"></param>
        /// <param name="nLoopOrder"></param>
        /// <param name="nRunTime"></param>
        /// <returns></returns>
        private List<HistorySampleData> GetHistorySimulatedData(int channelNumStart, int channelNumEnd, int nStepOrder, StepType stepType, int nLoopOrder, int nRunTime)
        {
            Random random = new Random();
            List<HistorySampleData> historyDataList = new List<HistorySampleData>();
            for (int n = channelNumStart; n <= channelNumEnd; n++)
            {
                if (!testUuidMap.ContainsKey(n))
                {
                    continue;
                }
                recordIndexMap[n] = recordIndexMap[n] + 1;
                HistorySampleData historySampleData = new HistorySampleData();
                //1   Uint8_t 工步类型    1   参考工步类型数据结构
                historySampleData.stepType = stepType.StepValue;
                //2   Uint8_t 事件码 1   事件码
                historySampleData.eventCode = random.Next(1, 10);
                //3   Uint16_t 通道号 2   通道号
                historySampleData.channel = n;
                // UUID	4
                historySampleData.UUID = testUuidMap[n];
                //4   Uint16_t 工步序号    2   工步序号
                historySampleData.stepNo = nStepOrder + 1;
                //5   Uint16_t 当前循环号   2   当前循环正在执行的循环号
                historySampleData.loopIndex = nLoopOrder;
                //6   Uint32_t 步次号 4   从1开始，每执行一个工步递增1
                historySampleData.stepOrder = random.Next(1, 10);
                //7   uint32_t 数据记录索引  4   数据记录索引,从1开始，每记录一条 + 1
                historySampleData.dataRecordIndex = recordIndexMap[n];
                //8   uint32_t 运行时间    4   当前工步运行时间值（S）
                historySampleData.runTime = nRunTime;
                //9   uint32_t 绝对时间    4   Unix时间
                DateTime now = DateTime.Now;
                STLocTime stLocTime = new STLocTime();
                stLocTime.Seconds = (uint)now.Second;
                stLocTime.Minutes = (uint)now.Minute;
                stLocTime.Hours = (uint)now.Hour;
                stLocTime.Day = (uint)now.Day;
                stLocTime.Month = (uint)now.Month;
                stLocTime.Year = ((uint)(now.Year % 2000));

                historySampleData.absoluteTime = stLocTime.uiLoTime;

                //充电
                //10  uint32_t 电池电压    4   电压值（V）
                historySampleData.batteryVoltage = random.Next(10000, 90000);
                //11  uint32_t 电压2 4   电压值（V）
                historySampleData.voltage2 = random.Next(10000, 20000);

                if (stepType.nType == 0)
                {
                    //充电
                    //12  uint32_t 通道电流    4   电流值(A)
                    historySampleData.channelCurrent = random.Next(10000, 20000);
                }
                else if (stepType.nType == 1)
                {
                    //放电
                    //12  uint32_t 通道电流    4   电流值(A)
                    historySampleData.channelCurrent = random.Next(-15000, -10000);
                }
                else
                {
                    //12  uint32_t 通道电流    4   电流值(A)
                    historySampleData.channelCurrent = random.Next(10000, 20000);
                }
                //13  uint32_t 电池温度1   4   温度值(℃)
                historySampleData.batteryTemperature1 = random.Next(10, 990);
                //14  uint32_t 电池温度2   4   温度值(℃)
                historySampleData.batteryTemperature2 = random.Next(10, 990);
                //15  uint32_t 容量  4   容量值(Ah)
                historySampleData.realTimeCapacity = (int)(((historySampleData.channelCurrent / 10000.0) * (nRunTime / 1000.0 / 3600.0)) * 10000);
                //16  uint32_t 能量  4   能量值 电流*电压* (ts / 1000 / 3600);  -
                historySampleData.realTimeEnergy = (int)(((historySampleData.channelCurrent / 10000.0) * (historySampleData.batteryVoltage / 10000.0)) * (nRunTime / 1000.0 / 3600.0) * 10000);
                //17  uint32_t 直流内阻    4   内阻值
                historySampleData.dcInnerResistance = random.Next(1000, 10000);
                //18  uint32_t 接触阻抗    4   接触阻抗值
                historySampleData.contactResistance = random.Next(1000, 10000);
                //19  Uint16_t 环境温度1   2   温度值(℃)
                historySampleData.environmentTemperature1 = random.Next(10, 990);
                //20  Uint16_t 环境温度2   2   温度值(℃)
                historySampleData.environmentTemperature2 = random.Next(10, 990);
                //23  Uint16_t 火警温度    2   温度值(℃)
                historySampleData.fireAlarmTemperature = random.Next(10, 990);
                //24  uint32_t 环境值 4	//真空压力或其它环境参数值
                historySampleData.environmentVal = random.Next(10, 990);
                //25  uint32_t 预留  10x4 预留
                historyDataList.Add(historySampleData);
            }
            return historyDataList;
        }

        #endregion ___模拟历史数据___

        #region 序列化 历史数据

        /// <summary>
        /// 历史数据转二进制
        /// </summary>
        /// <param name="historySampleDatas"></param>
        /// <returns></returns>
        private byte[] SerializeHistoryData(List<HistorySampleData> historySampleDatas)
        {
            Random random = new Random();
            List<byte> byteData = new List<byte>();
            foreach (HistorySampleData historySampleData in historySampleDatas)
            {
                //1   Uint8_t 工步类型    1   参考工步类型数据结构
                byteData.Add(Convert.ToByte(historySampleData.stepType & 0xFF));
                //2   Uint16_t 事件码 2  事件码
                byteData.AddRange(IntToByte2(historySampleData.eventCode));
                //3   Uint16_t 通道号 2   通道号
                byteData.AddRange(IntToByte2(historySampleData.channel));
                //4   Uint16_t 工步序号    2   工步序号
                byteData.AddRange(IntToByte2(historySampleData.stepNo));
                //5   Uint16_t 当前循环号   2   当前循环正在执行的循环号
                byteData.AddRange(IntToByte2(historySampleData.loopIndex));
                //6 uint32_t	UUID	4
                byte[] byteUuid = BitConverter.GetBytes(historySampleData.UUID);
                if (!BitConverter.IsLittleEndian)
                {
                    byteUuid.Reverse();
                }
                byteData.AddRange(byteUuid);
                //7   Uint32_t 步次号 4   从1开始，每执行一个工步递增1
                byteData.AddRange(IntToByte4(historySampleData.stepOrder));
                //8   uint32_t 数据记录索引  4   数据记录索引,从1开始，每记录一条 + 1
                byteData.AddRange(IntToByte4(historySampleData.dataRecordIndex));
                //9   uint32_t 运行时间    4   当前工步运行时间值（S）
                byteData.AddRange(IntToByte4(historySampleData.runTime));
                //10   uint32_t 绝对时间    4   Unix时间
                byte[] byteArr = BitConverter.GetBytes(historySampleData.absoluteTime);
                byteData.AddRange(byteArr);
                //11  uint32_t 电池电压    4   电压值（V）
                byteData.AddRange(IntToByte4(historySampleData.batteryVoltage));
                //12  uint32_t 电压2 4   电压值（V）
                byteData.AddRange(IntToByte4(historySampleData.voltage2));
                //13  uint32_t 通道电流    4   电流值(A)
                byteData.AddRange(IntToByte4(historySampleData.channelCurrent));

                //14  uint32_t 电池温度1   2    温度值(℃)
                byteData.AddRange(IntToByte2(historySampleData.batteryTemperature1));
                //15  uint32_t 电池温度2   2   温度值(℃)
                byteData.AddRange(IntToByte2(historySampleData.batteryTemperature2));
                //16  uint32_t 容量  4   容量值(Ah)
                byteData.AddRange(IntToByte4(historySampleData.realTimeCapacity));
                //17  uint32_t 能量  4   能量值
                byteData.AddRange(IntToByte4(historySampleData.realTimeEnergy));
                //18  uint32_t 直流内阻    4   内阻值
                byteData.AddRange(IntToByte4(historySampleData.dcInnerResistance));
                //19  uint32_t 接触阻抗    4   接触阻抗值
                byteData.AddRange(IntToByte4(historySampleData.contactResistance));

                //20  Uint16_t 环境温度1   2   温度值(℃)
                byteData.AddRange(IntToByte2(historySampleData.environmentTemperature1));
                //21  Uint16_t 环境温度2   2   温度值(℃)
                byteData.AddRange(IntToByte2(historySampleData.environmentTemperature2));
                //22  Uint16_t 火警温度    2   温度值(℃)
                byteData.AddRange(IntToByte2(historySampleData.fireAlarmTemperature));
                //23  uint32_t 环境值 4	//真空压力或其它环境参数值
                byteData.AddRange(IntToByte4(historySampleData.environmentVal));
                //24  uint32_t 预留  8x4 预留
                byteData.AddRange(new byte[8 * 4]);
            }
            return byteData.ToArray();
        }

        #endregion 序列化 历史数据

        #region ___工具函数____

        /// <summary>
        ///   List<int>转为byte字节数组-- int值几就设置第几个bit设置为1
        ///   int 值从1开始
        /// List<int> flags 中的
        /// int值比如是 1，那么返回一个byte 的bit0是1，
        /// int值比如是 5，那么返回一个byte 的bit4是1，
        /// int值比如是 8，那么返回一个byte 的bit7是1，
        /// </summary>
        /// <param name="flags"></param>
        /// <param name="nOutByteCount">返回的字节数</param>
        /// <returns></returns>
        public byte[] ConvertIntToByteFlag(List<int> flags, int nOutByteCount)
        {
            byte[] bts = new byte[nOutByteCount];
            foreach (int flag in flags)
            {
                if (flag >= 1 && flag <= nOutByteCount * 8)
                {
                    int byteIndex = (flag - 1) / 8;
                    int bitIndex = (flag - 1) % 8;
                    bts[byteIndex] |= (byte)(1 << bitIndex);
                }
            }
            return bts;
        }

        /// <summary>
        /// 入参是byte[] 返回是List<int>的函数
        /// 比如：
        /// byte[0]的bit0=1 。list中添加int类型值1
        /// byte[0]的bit5=1 。list中添加int类型值6
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        public List<int> ConvertByteFlagToInt(byte[] bytes)
        {
            List<int> flags = new List<int>();
            for (int i = 0; i < bytes.Length; i++)
            {
                byte b = bytes[i];
                for (int j = 0; j < 8; j++)
                {
                    if ((b & (1 << j)) != 0)
                    {
                        flags.Add(i * 8 + j + 1);
                    }
                }
            }
            return flags;
        }

        /// <summary>
        /// 自定义的窗口 弹出消息
        /// </summary>
        /// <param name="strjson"></param>
        public void UseFormShowMsg(string strjson)
        {
            System.Windows.Forms.Form form = new System.Windows.Forms.Form();
            form.Height = System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height - 100;
            form.Width = 500;
            form.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;

            System.Windows.Forms.TextBox textBox = new System.Windows.Forms.TextBox();
            textBox.Multiline = true;
            textBox.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
            textBox.Dock = System.Windows.Forms.DockStyle.Fill;
            textBox.Text = "MedianService:" + strjson;
            form.Controls.Add(textBox);
            form.ShowDialog();
        }

        /*高字CRC*/

        public static byte[] auchCRCHi = {
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81,
0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81,
0x40, 0x01, 0xC0,
0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1,
0x81, 0x40, 0x01,
0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01,
0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81,
0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80,
0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x01,
0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00,
0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81,
0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
0x40, 0x01, 0xC0,
0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1,
0x81, 0x40, 0x01,
0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01,
0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81,
0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
0x40, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x01,
0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01,
0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81,
0x40
};

        /*低字CRC*/

        public static byte[] auchCRCLo = {
0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7,0x05, 0xC5, 0xC4,
0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB,0x0B, 0xC9, 0x09,
0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE,0xDF, 0x1F, 0xDD,
0x1D, 0x1C, 0xDC, 0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2,0x12, 0x13, 0xD3,
0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32,0x36, 0xF6, 0xF7,
0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E,0xFE, 0xFA, 0x3A,
0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B,0x2A, 0xEA, 0xEE,
0x2E, 0x2F, 0xEF, 0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27,0xE7, 0xE6, 0x26,
0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1,0x63, 0xA3, 0xA2,
0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD,0x6D, 0xAF, 0x6F,
0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8,0xB9, 0x79, 0xBB,
0x7B, 0x7A, 0xBA, 0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4,0x74, 0x75, 0xB5,
0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0,0x50, 0x90, 0x91,
0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94,0x54, 0x9C, 0x5C,
0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59,0x58, 0x98, 0x88,
0x48, 0x49, 0x89, 0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D,0x4D, 0x4C, 0x8C,
0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83,0x41, 0x81, 0x80,
0x40
};

        public byte[] Crc16(byte[] puchMsg)
        {
            return CRCHelper.Crc16_2(puchMsg);
        }

        /// <summary>
        /// CRC16
        /// </summary>
        /// <param name="buffer"></param>
        /// <returns></returns>
        public List<byte> Crc16_OLD(byte[] buffer)
        {
            List<byte> byteDate = new List<byte>();
            ushort crc = 0xFFFF;
            int size = buffer.Length;
            int i = 0;
            if (size > 0)
            {
                while (size-- > 0)
                {
                    crc = (ushort)((crc >> 8) | (crc << 8));
                    crc ^= buffer[i++];
                    crc ^= (ushort)(((byte)crc) >> 4);
                    crc ^= (ushort)(crc << 12);
                    crc ^= (ushort)((crc & 0xff) << 5);
                }
            }
            byteDate.Add((byte)((crc >> 8) & 0xff));
            byteDate.Add((byte)(crc & 0xff));
            return byteDate;
        }

        /// <summary>
        /// 整型转字节,低字节在前-高字节在后
        /// </summary>
        /// <param name="caseNo"></param>
        /// <returns></returns>
        public List<byte> IntToByte2(int data)
        {
            List<byte> address = new List<byte>();
            var udataLength = (ushort)(data);
            address.Add((byte)(0xff & udataLength));
            address.Add((byte)((0xff00 & udataLength) >> 8));
            return address;
        }

        /// <summary>
        /// 整型转字节,低字节在前-高字节在后
        /// </summary>
        /// <param name="caseNo"></param>
        /// <returns></returns>
        public List<byte> IntToByte4(int data)
        {
            List<byte> address = new List<byte>();
            address.Add((byte)(data & 0xFF));
            address.Add((byte)((data >> 8) & 0xFF));
            address.Add((byte)((data >> 16) & 0xFF));
            address.Add((byte)((data >> 24) & 0xFF));
            return address;
        }

        #endregion ___工具函数____
    }
}